+}
+
+static void
+qla1280_set_target_defaults(struct scsi_qla_host *ha, int bus, int target)
+{
+ struct nvram *nv = &ha->nvram;
+
+ nv->bus[bus].target[target].parameter.renegotiate_on_error = 1;
+ nv->bus[bus].target[target].parameter.auto_request_sense = 1;
+ nv->bus[bus].target[target].parameter.tag_queuing = 1;
+ nv->bus[bus].target[target].parameter.enable_sync = 1;
+#if 1 /* Some SCSI Processors do not seem to like this */
+ nv->bus[bus].target[target].parameter.enable_wide = 1;
+#endif
+ nv->bus[bus].target[target].execution_throttle =
+ nv->bus[bus].max_queue_depth - 1;
+ nv->bus[bus].target[target].parameter.parity_checking = 1;
+ nv->bus[bus].target[target].parameter.disconnect_allowed = 1;
+
+ if (IS_ISP1x160(ha)) {
+ nv->bus[bus].target[target].flags.flags1x160.device_enable = 1;
+ nv->bus[bus].target[target].flags.flags1x160.sync_offset = 0x0e;
+ nv->bus[bus].target[target].sync_period = 9;
+ nv->bus[bus].target[target].ppr_1x160.flags.enable_ppr = 1;
+ nv->bus[bus].target[target].ppr_1x160.flags.ppr_options = 2;
+ nv->bus[bus].target[target].ppr_1x160.flags.ppr_bus_width = 1;
+ } else {
+ nv->bus[bus].target[target].flags.flags1x80.device_enable = 1;
+ nv->bus[bus].target[target].flags.flags1x80.sync_offset = 12;
+ nv->bus[bus].target[target].sync_period = 10;
+ }
+}
+
+static void
+qla1280_set_defaults(struct scsi_qla_host *ha)
+{
+ struct nvram *nv = &ha->nvram;
+ int bus, target;
+
+ dprintk(1, "Using defaults for NVRAM: \n");
+ memset(nv, 0, sizeof(struct nvram));
+
+ /* nv->cntr_flags_1.disable_loading_risc_code = 1; */
+ nv->firmware_feature.f.enable_fast_posting = 1;
+ nv->firmware_feature.f.disable_synchronous_backoff = 1;
+ nv->termination.scsi_bus_0_control = 3;
+ nv->termination.scsi_bus_1_control = 3;
+ nv->termination.auto_term_support = 1;
+
+ /*
+ * Set default FIFO magic - What appropriate values would be here
+ * is unknown. This is what I have found testing with 12160s.
+ *
+ * Now, I would love the magic decoder ring for this one, the
+ * header file provided by QLogic seems to be bogus or incomplete
+ * at best.
+ */
+ nv->isp_config.burst_enable = 1;
+ if (IS_ISP1040(ha))
+ nv->isp_config.fifo_threshold |= 3;
+ else
+ nv->isp_config.fifo_threshold |= 4;
+
+ if (IS_ISP1x160(ha))
+ nv->isp_parameter = 0x01; /* fast memory enable */
+
+ for (bus = 0; bus < MAX_BUSES; bus++) {
+ nv->bus[bus].config_1.initiator_id = 7;
+ nv->bus[bus].config_2.req_ack_active_negation = 1;
+ nv->bus[bus].config_2.data_line_active_negation = 1;
+ nv->bus[bus].selection_timeout = 250;
+ nv->bus[bus].max_queue_depth = 256;
+
+ if (IS_ISP1040(ha)) {
+ nv->bus[bus].bus_reset_delay = 3;
+ nv->bus[bus].config_2.async_data_setup_time = 6;
+ nv->bus[bus].retry_delay = 1;
+ } else {
+ nv->bus[bus].bus_reset_delay = 5;
+ nv->bus[bus].config_2.async_data_setup_time = 8;
+ }
+
+ for (target = 0; target < MAX_TARGETS; target++)
+ qla1280_set_target_defaults(ha, bus, target);
+ }
+}
+
+static int
+qla1280_config_target(struct scsi_qla_host *ha, int bus, int target)
+{
+ struct nvram *nv = &ha->nvram;
+ uint16_t mb[MAILBOX_REGISTER_COUNT];
+ int status, lun;
+ uint16_t flag;
+
+ /* Set Target Parameters. */
+ mb[0] = MBC_SET_TARGET_PARAMETERS;
+ mb[1] = (uint16_t)((bus ? target | BIT_7 : target) << 8);
+
+ /*
+ * Do not enable sync and ppr for the initial INQUIRY run. We
+ * enable this later if we determine the target actually
+ * supports it.
+ */
+ mb[2] = (TP_RENEGOTIATE | TP_AUTO_REQUEST_SENSE | TP_TAGGED_QUEUE
+ | TP_WIDE | TP_PARITY | TP_DISCONNECT);
+
+ if (IS_ISP1x160(ha))
+ mb[3] = nv->bus[bus].target[target].flags.flags1x160.sync_offset << 8;
+ else
+ mb[3] = nv->bus[bus].target[target].flags.flags1x80.sync_offset << 8;
+ mb[3] |= nv->bus[bus].target[target].sync_period;
+ status = qla1280_mailbox_command(ha, 0x0f, mb);
+
+ /* Save Tag queuing enable flag. */
+ flag = (BIT_0 << target) & mb[0];
+ if (nv->bus[bus].target[target].parameter.tag_queuing)
+ ha->bus_settings[bus].qtag_enables |= flag;
+
+ /* Save Device enable flag. */
+ if (IS_ISP1x160(ha)) {
+ if (nv->bus[bus].target[target].flags.flags1x160.device_enable)
+ ha->bus_settings[bus].device_enables |= flag;
+ ha->bus_settings[bus].lun_disables |= 0;
+ } else {
+ if (nv->bus[bus].target[target].flags.flags1x80.device_enable)
+ ha->bus_settings[bus].device_enables |= flag;
+ /* Save LUN disable flag. */
+ if (nv->bus[bus].target[target].flags.flags1x80.lun_disable)
+ ha->bus_settings[bus].lun_disables |= flag;
+ }
+
+ /* Set Device Queue Parameters. */
+ for (lun = 0; lun < MAX_LUNS; lun++) {
+ mb[0] = MBC_SET_DEVICE_QUEUE;
+ mb[1] = (uint16_t)((bus ? target | BIT_7 : target) << 8);
+ mb[1] |= lun;
+ mb[2] = nv->bus[bus].max_queue_depth;
+ mb[3] = nv->bus[bus].target[target].execution_throttle;
+ status |= qla1280_mailbox_command(ha, 0x0f, mb);
+ }
+
+ return status;
+}
+
+static int
+qla1280_config_bus(struct scsi_qla_host *ha, int bus)
+{
+ struct nvram *nv = &ha->nvram;
+ uint16_t mb[MAILBOX_REGISTER_COUNT];
+ int target, status;
+
+ /* SCSI Reset Disable. */
+ ha->bus_settings[bus].disable_scsi_reset =
+ nv->bus[bus].config_1.scsi_reset_disable;
+
+ /* Initiator ID. */
+ ha->bus_settings[bus].id = nv->bus[bus].config_1.initiator_id;
+ mb[0] = MBC_SET_INITIATOR_ID;
+ mb[1] = bus ? ha->bus_settings[bus].id | BIT_7 :
+ ha->bus_settings[bus].id;
+ status = qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]);
+
+ /* Reset Delay. */
+ ha->bus_settings[bus].bus_reset_delay =
+ nv->bus[bus].bus_reset_delay;
+
+ /* Command queue depth per device. */
+ ha->bus_settings[bus].hiwat = nv->bus[bus].max_queue_depth - 1;
+
+ /* Set target parameters. */
+ for (target = 0; target < MAX_TARGETS; target++)
+ status |= qla1280_config_target(ha, bus, target);
+
+ return status;
+}
+
+static int
+qla1280_nvram_config(struct scsi_qla_host *ha)
+{
+ struct device_reg __iomem *reg = ha->iobase;
+ struct nvram *nv = &ha->nvram;
+ int bus, target, status = 0;
+ uint16_t mb[MAILBOX_REGISTER_COUNT];
+
+ ENTER("qla1280_nvram_config");
+
+ if (ha->nvram_valid) {
+ /* Always force AUTO sense for LINUX SCSI */
+ for (bus = 0; bus < MAX_BUSES; bus++)
+ for (target = 0; target < MAX_TARGETS; target++) {
+ nv->bus[bus].target[target].parameter.
+ auto_request_sense = 1;
+ }
+ } else {
+ qla1280_set_defaults(ha);
+ }
+
+ qla1280_print_settings(nv);