diff options
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/qlogicfc.c | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/drivers/scsi/qlogicfc.c b/drivers/scsi/qlogicfc.c index 798122f50..bd8f27e14 100644 --- a/drivers/scsi/qlogicfc.c +++ b/drivers/scsi/qlogicfc.c @@ -907,7 +907,6 @@ static int isp2x00_make_portdb(struct Scsi_Host *host) isp2x00_mbox_command(host, param); -/* XXX cpu_to_le16 ?? */ if (param[0] == MBOX_COMMAND_COMPLETE) { temp[j].loop_id = i; temp[j].wwn = ((u64) (param[2] & 0xff)) << 56; @@ -1241,7 +1240,7 @@ int isp2x00_queuecommand(Scsi_Cmnd * Cmnd, void (*done) (Scsi_Cmnd *)) for (i = in_ptr; i != (in_ptr - 1) && hostdata->handle_ptrs[i]; i = ((i + 1) % (QLOGICFC_REQ_QUEUE_LEN + 1))); if (!hostdata->handle_ptrs[i]) { - cmd->handle = i; + cmd->handle = cpu_to_le32(i); hostdata->handle_ptrs[i] = Cmnd; hostdata->handle_serials[i] = Cmnd->serial_number; } else { @@ -1366,6 +1365,13 @@ int isp2x00_queuecommand(Scsi_Cmnd * Cmnd, void (*done) (Scsi_Cmnd *)) break; } } + /* + * TEST_UNIT_READY commands from scsi_scan will fail due to "overlapped + * commands attempted" unless we setup at least a simple queue (midlayer + * will embelish this once it can do an INQUIRY command to the device) + */ + else + cmd->control_flags |= cpu_to_le16(CFLAG_SIMPLE_TAG); outw(in_ptr, host->io_port + MBOX4); hostdata->req_in_ptr = in_ptr; @@ -1549,12 +1555,14 @@ void isp2x00_intr_handler(int irq, void *dev_id, struct pt_regs *regs) DEBUG_INTR(printk("qlogicfc%d : response queue depth %d\n", hostdata->host_id, RES_QUEUE_DEPTH(in_ptr, out_ptr))); while (out_ptr != in_ptr) { + unsigned le_hand; sts = (struct Status_Entry *) &hostdata->res[out_ptr*QUEUE_ENTRY_LEN]; out_ptr = (out_ptr + 1) & RES_QUEUE_LEN; TRACE("done", out_ptr, Cmnd); DEBUG_INTR(isp2x00_print_status_entry(sts)); - if (sts->hdr.entry_type == ENTRY_STATUS && (Cmnd = hostdata->handle_ptrs[sts->handle])) { + le_hand = le32_to_cpu(sts->handle); + if (sts->hdr.entry_type == ENTRY_STATUS && (Cmnd = hostdata->handle_ptrs[le_hand])) { Cmnd->result = isp2x00_return_status(Cmnd, sts); hostdata->queued--; @@ -1573,10 +1581,10 @@ void isp2x00_intr_handler(int irq, void *dev_id, struct pt_regs *regs) * we dont have to call done because the upper * level should already know its aborted. */ - if (hostdata->handle_serials[sts->handle] != Cmnd->serial_number + if (hostdata->handle_serials[le_hand] != Cmnd->serial_number || le16_to_cpu(sts->completion_status) == CS_ABORTED){ - hostdata->handle_serials[sts->handle] = 0; - hostdata->handle_ptrs[sts->handle] = NULL; + hostdata->handle_serials[le_hand] = 0; + hostdata->handle_ptrs[le_hand] = NULL; outw(out_ptr, host->io_port + MBOX5); continue; } @@ -1597,7 +1605,7 @@ void isp2x00_intr_handler(int irq, void *dev_id, struct pt_regs *regs) continue; } - hostdata->handle_ptrs[sts->handle] = NULL; + hostdata->handle_ptrs[le_hand] = NULL; if (sts->completion_status == cpu_to_le16(CS_RESET_OCCURRED) || (sts->status_flags & cpu_to_le16(STF_BUS_RESET))) |