patch-2.2.6 linux/drivers/scsi/qlogicfc.c
Next file: linux/drivers/scsi/qlogicfc_asm.c
Previous file: linux/drivers/scsi/psi_roy.h
Back to the patch index
Back to the overall index
- Lines: 311
- Date:
Thu Apr 15 05:42:43 1999
- Orig file:
v2.2.5/linux/drivers/scsi/qlogicfc.c
- Orig date:
Wed Mar 10 15:29:47 1999
diff -u --recursive --new-file v2.2.5/linux/drivers/scsi/qlogicfc.c linux/drivers/scsi/qlogicfc.c
@@ -64,12 +64,13 @@
/* Configuration section **************************************************** */
/* Set the following macro to 1 to reload the ISP2100's firmware. This is
- version 1.13 of the firmware. */
+ version 1.15.19 of the firmware. */
#define RELOAD_FIRMWARE 1
#define USE_NVRAM_DEFAULTS 1
+#define ISP2100_PORTDB 1
/* Set the following to 1 to include fabric support, fabric support is
* currently not as well tested as the other aspects of the driver */
@@ -316,16 +317,13 @@
/* status entry completion status definitions */
#define CS_COMPLETE 0x0000
-#define CS_INCOMPLETE 0x0001
#define CS_DMA_ERROR 0x0002
-#define CS_TRANSPORT_ERROR 0x0003
#define CS_RESET_OCCURRED 0x0004
#define CS_ABORTED 0x0005
#define CS_TIMEOUT 0x0006
#define CS_DATA_OVERRUN 0x0007
-#define CS_ABORT_MSG_FAILED 0x000e
-#define CS_REJECT_MSG_FAILED 0x000f
#define CS_DATA_UNDERRUN 0x0015
+#define CS_QUEUE_FULL 0x001c
#define CS_PORT_UNAVAILABLE 0x0028
#define CS_PORT_LOGGED_OUT 0x0029
#define CS_PORT_CONFIG_CHANGED 0x002a
@@ -645,9 +643,7 @@
static void isp2100_print_scsi_cmd(Scsi_Cmnd *);
#endif
-#if DEBUG_ISP2100_INTR
static void isp2100_print_status_entry(struct Status_Entry *);
-#endif
static struct proc_dir_entry proc_scsi_isp2100 =
{
@@ -721,7 +717,7 @@
scsi_unregister(host);
continue;
}
- host->this_id = tmpt->this_id;
+ host->this_id = 0;
if (request_irq(host->irq, do_isp2100_intr_handler, SA_INTERRUPT | SA_SHIRQ, "qlogicfc", host)) {
printk("qlogicfc : interrupt %d already in use\n",
@@ -743,7 +739,7 @@
outw(HCCR_CLEAR_RISC_INTR, host->io_port + HOST_HCCR);
isp2100_enable_irqs(host);
/* wait for the loop to come up */
- for (wait_time = jiffies + 20 * HZ; wait_time > jiffies && hostdata->loop_up == 0;)
+ for (wait_time = jiffies + 10 * HZ; wait_time > jiffies && hostdata->loop_up == 0;)
barrier();
if (hostdata->loop_up == 0) {
@@ -805,13 +801,17 @@
isp2100_mbox_command(host, param);
if (param[0] == MBOX_COMMAND_COMPLETE) {
- host->this_id = param[1];
hostdata->port_id = ((u_int) param[3]) << 16;
hostdata->port_id |= param[2];
+ temp[0].loop_id = param[1];
+ temp[0].wwn = hostdata->wwn;
+ }
+ else {
+ printk("qlogicfc: error getting scsi id.\n");
}
- for (i = 0, j = 0; i <= QLOGICFC_MAX_ID; i++) {
- temp[i].loop_id = host->this_id;
+ for (i = 1, j = 1; i <= QLOGICFC_MAX_ID; i++) {
+ temp[i].loop_id = temp[0].loop_id;
param[0] = MBOX_GET_PORT_NAME;
param[1] = (i << 8) & 0xff00;
@@ -848,7 +848,7 @@
}
}
if (j == QLOGICFC_MAX_ID + 1)
- hostdata->port_db[i].loop_id = host->this_id;
+ hostdata->port_db[i].loop_id = temp[0].loop_id;
for (j = 0; j <= QLOGICFC_MAX_ID; j++) {
if (hostdata->port_db[j].wwn == temp[i].wwn || !hostdata->port_db[j].wwn) {
@@ -1046,6 +1046,7 @@
host->max_id = 0;
return 0;
}
+
out_ptr = inw(host->io_port + MBOX4);
in_ptr = hostdata->req_in_ptr;
@@ -1099,10 +1100,13 @@
cmd->hdr.entry_type = ENTRY_COMMAND;
cmd->hdr.entry_cnt = 1;
cmd->target_lun = Cmnd->lun;
+#if ISP2100_PORTDB
cmd->target_id = hostdata->port_db[Cmnd->target].loop_id;
+#else
+ cmd->target_id = Cmnd->target;
+#endif
cmd->total_byte_cnt = (u_int) Cmnd->request_bufflen;
- cmd->time_out = SCSI_TIMEOUT / HZ;
-
+ cmd->time_out = (SCSI_TIMEOUT / HZ) * 5;
memcpy(cmd->cdb, Cmnd->cmnd, Cmnd->cmd_len);
if (Cmnd->use_sg) {
@@ -1173,41 +1177,38 @@
if (Cmnd->device->tagged_supported) {
- switch (Cmnd->tag) {
- case SIMPLE_QUEUE_TAG:
- cmd->control_flags |= CFLAG_SIMPLE_TAG;
- break;
- case HEAD_OF_QUEUE_TAG:
- cmd->control_flags |= CFLAG_HEAD_TAG;
- break;
- case ORDERED_QUEUE_TAG:
+ if ((jiffies - hostdata->tag_ages[Cmnd->target]) > (2 * SCSI_TIMEOUT)) {
cmd->control_flags |= CFLAG_ORDERED_TAG;
- break;
- default:
- if ((jiffies - hostdata->tag_ages[Cmnd->target]) > (5 * HZ)) {
+ hostdata->tag_ages[Cmnd->target] = jiffies;
+ } else
+ switch (Cmnd->tag) {
+ case HEAD_OF_QUEUE_TAG:
+ cmd->control_flags |= CFLAG_HEAD_TAG;
+ break;
+ case ORDERED_QUEUE_TAG:
cmd->control_flags |= CFLAG_ORDERED_TAG;
- hostdata->tag_ages[Cmnd->target] = jiffies;
- } else
+ break;
+ default:
cmd->control_flags |= CFLAG_SIMPLE_TAG;
+ break;
}
}
outw(in_ptr, host->io_port + MBOX4);
hostdata->req_in_ptr = in_ptr;
hostdata->queued++;
-
num_free = QLOGICFC_REQ_QUEUE_LEN - REQ_QUEUE_DEPTH(in_ptr, out_ptr);
- num_free = num_free - 2;
+ num_free = (num_free > 2) ? num_free - 2 : 0;
host->can_queue = hostdata->queued + num_free;
if (host->can_queue > QLOGICFC_REQ_QUEUE_LEN)
host->can_queue = QLOGICFC_REQ_QUEUE_LEN;
host->sg_tablesize = QLOGICFC_MAX_SG(num_free);
/* this is really gross */
- if (host->can_queue < host->host_busy){
+ if (host->can_queue <= host->host_busy){
if (host->can_queue+2 < host->host_busy)
- printk("qlogicfc.c crosses its fingers.\n");
- host->can_queue = host->host_busy;
+ DEBUG(printk("qlogicfc.c crosses its fingers.\n"));
+ host->can_queue = host->host_busy + 1;
}
LEAVE("isp2100_queuecommand");
@@ -1310,22 +1311,20 @@
while (out_ptr != in_ptr) {
sts = (struct Status_Entry *) &hostdata->res[out_ptr][0];
out_ptr = (out_ptr + 1) & RES_QUEUE_LEN;
- Cmnd = hostdata->handle_ptrs[sts->handle];
-
- hostdata->handle_ptrs[sts->handle] = NULL;
-
- if (hostdata->handle_serials[sts->handle] != Cmnd->serial_number) {
- hostdata->queued--;
- hostdata->handle_serials[sts->handle] = 0;
- outw(out_ptr, host->io_port + MBOX5);
- continue;
- }
- hostdata->handle_serials[sts->handle] = 0;
-
+
TRACE("done", out_ptr, Cmnd);
DEBUG_INTR(isp2100_print_status_entry(sts));
if (sts->hdr.entry_type == ENTRY_STATUS) {
+ Cmnd = hostdata->handle_ptrs[sts->handle];
Cmnd->result = isp2100_return_status(sts);
+ hostdata->handle_ptrs[sts->handle] = NULL;
+ hostdata->queued--;
+ if (hostdata->handle_serials[sts->handle] != Cmnd->serial_number) {
+ hostdata->handle_serials[sts->handle] = 0;
+ outw(out_ptr, host->io_port + MBOX5);
+ continue;
+ }
+ hostdata->handle_serials[sts->handle] = 0;
} else {
outw(out_ptr, host->io_port + MBOX5);
continue;
@@ -1336,13 +1335,13 @@
|| (sts->status_flags & STF_BUS_RESET))
hostdata->send_marker = 1;
+ memset(Cmnd->sense_buffer, 0, sizeof(Cmnd->sense_buffer));
if (sts->scsi_status & 0x0200)
memcpy(Cmnd->sense_buffer, sts->req_sense_data,
sizeof(Cmnd->sense_buffer));
outw(out_ptr, host->io_port + MBOX5);
- hostdata->queued--;
if (Cmnd->scsi_done != NULL) {
(*Cmnd->scsi_done) (Cmnd);
} else
@@ -1356,16 +1355,16 @@
in_ptr = hostdata->req_in_ptr;
num_free = QLOGICFC_REQ_QUEUE_LEN - REQ_QUEUE_DEPTH(in_ptr, out_ptr);
- num_free = num_free-2;
+ num_free = (num_free > 2) ? num_free - 2 : 0;
host->can_queue = hostdata->queued + num_free;
if (host->can_queue > QLOGICFC_REQ_QUEUE_LEN)
host->can_queue = QLOGICFC_REQ_QUEUE_LEN;
host->sg_tablesize = QLOGICFC_MAX_SG(num_free);
- if (host->can_queue < host->host_busy){
+ if (host->can_queue <= host->host_busy){
if (host->can_queue+2 < host->host_busy)
DEBUG(printk("qlogicfc crosses its fingers.\n"));
- host->can_queue = host->host_busy;
+ host->can_queue = host->host_busy + 1;
}
outw(HCCR_CLEAR_RISC_INTR, host->io_port + HOST_HCCR);
@@ -1401,16 +1400,7 @@
case CS_COMPLETE:
host_status = DID_OK;
break;
- case CS_INCOMPLETE:
- if (!(sts->state_flags & SF_SENT_CDB))
- host_status = DID_ERROR;
- else if (!(sts->state_flags & SF_TRANSFERRED_DATA))
- host_status = DID_ERROR;
- else if (!(sts->state_flags & SF_GOT_STATUS))
- host_status = DID_ERROR;
- break;
case CS_DMA_ERROR:
- case CS_TRANSPORT_ERROR:
host_status = DID_ERROR;
break;
case CS_RESET_OCCURRED:
@@ -1423,7 +1413,6 @@
host_status = DID_TIME_OUT;
break;
case CS_DATA_OVERRUN:
- case CS_ABORT_MSG_FAILED:
host_status = DID_ERROR;
break;
case CS_DATA_UNDERRUN:
@@ -1434,6 +1423,9 @@
case CS_PORT_CONFIG_CHANGED:
host_status = DID_BAD_TARGET;
break;
+ case CS_QUEUE_FULL:
+ host_status = DID_ERROR;
+ break;
default:
printk("qlogicfc : unknown completion status 0x%04x\n",
sts->completion_status);
@@ -1539,8 +1531,6 @@
ip[0] = 255;
ip[1] = 63;
ip[2] = size / (ip[0] * ip[1]);
- if (ip[2] > 1023)
- ip[2] = 1023;
}
LEAVE("isp2100_biosparam");
@@ -1678,9 +1668,6 @@
if (isp2100_read_nvram_word(host, 0) != 0x5349)
return 1;
- control_block->max_frame_len = isp2100_read_nvram_word(host, 5);
- control_block->max_iocb = isp2100_read_nvram_word(host, 6);
- control_block->exec_throttle = isp2100_read_nvram_word(host, 7);
value = isp2100_read_nvram_word(host, 8);
control_block->node_name[0] = isp2100_read_nvram_word(host, 9);
control_block->node_name[1] = isp2100_read_nvram_word(host, 10);
@@ -1892,8 +1879,6 @@
}
-#if DEBUG_ISP2100_INTR
-
void isp2100_print_status_entry(struct Status_Entry *status)
{
printk("qlogicfc : entry count = 0x%02x, type = 0x%02x, flags = 0x%02x\n",
@@ -1908,7 +1893,6 @@
}
-#endif /* DEBUG_ISP2100_INTR */
#if DEBUG_ISP2100
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)