patch-2.2.4 linux/drivers/scsi/qlogicpti.c
Next file: linux/drivers/scsi/qlogicpti.h
Previous file: linux/drivers/scsi/psi_roy.h
Back to the patch index
Back to the overall index
- Lines: 276
- Date:
Mon Mar 15 16:11:31 1999
- Orig file:
v2.2.3/linux/drivers/scsi/qlogicpti.c
- Orig date:
Mon Oct 5 13:13:40 1998
diff -u --recursive --new-file v2.2.3/linux/drivers/scsi/qlogicpti.c linux/drivers/scsi/qlogicpti.c
@@ -223,9 +223,15 @@
struct qlogicpti *qpti = (struct qlogicpti *) host->hostdata;
struct qlogicpti_regs *qregs = qpti->qregs;
u_short param[6];
+ unsigned short risc_code_addr;
int loop_count, i;
unsigned long flags;
+ if(qpti->is_pti != 0)
+ risc_code_addr = pti_risc_code_addr01;
+ else
+ risc_code_addr = sbus_risc_code_addr01;
+
save_flags(flags); cli();
qregs->hcctrl = HCCTRL_PAUSE;
@@ -264,7 +270,7 @@
/* Get RISC to start executing the firmware code. */
param[0] = MBOX_EXEC_FIRMWARE;
- param[1] = risc_code_addr01;
+ param[1] = risc_code_addr;
if(qlogicpti_mbox_command(qpti, param, 1)) {
printk(KERN_EMERG "qlogicpti%d: Cannot execute ISP firmware.\n",
qpti->qpti_id);
@@ -352,21 +358,32 @@
struct qlogicpti_regs *qregs = qpti->qregs;
unsigned short csum = 0;
unsigned short param[6];
+ unsigned short *risc_code, risc_code_addr, risc_code_length;
unsigned long flags;
#if !defined(MODULE) && !defined(__sparc_v9__)
unsigned long dvma_addr;
#endif
int i, timeout;
+ if(qpti->is_pti != 0) {
+ risc_code = &pti_risc_code01[0];
+ risc_code_addr = pti_risc_code_addr01;
+ risc_code_length = pti_risc_code_length01;
+ } else {
+ risc_code = &sbus_risc_code01[0];
+ risc_code_addr = sbus_risc_code_addr01;
+ risc_code_length = sbus_risc_code_length01;
+ }
+
save_flags(flags); cli();
/* Verify the checksum twice, one before loading it, and once
* afterwards via the mailbox commands.
*/
- for(i = 0; i < risc_code_length01; i++)
- csum += risc_code01[i];
+ for(i = 0; i < risc_code_length; i++)
+ csum += risc_code[i];
if(csum) {
- printk(KERN_EMERG "qlogicpti%d: AIeee, firmware checksum failed!",
+ printk(KERN_EMERG "qlogicpti%d: Aieee, firmware checksum failed!",
qpti->qpti_id);
return 1;
}
@@ -406,11 +423,6 @@
qpti->differential = 0;
qregs->hcctrl = HCCTRL_REL;
- /* XXX Talk to PTI engineer about the following, ISP always
- * XXX returns 0x4001 return status for stop firmware command,
- * XXX documentation claims this means the cmd is unsupported
- * XXX on this ISP. I think something fishy is going on.
- */
param[0] = MBOX_STOP_FIRMWARE;
param[1] = param[2] = param[3] = param[4] = param[5] = 0;
if(qlogicpti_mbox_command(qpti, param, 1)) {
@@ -423,13 +435,13 @@
/* Load the firmware. */
#if !defined(MODULE) && !defined(__sparc_v9__)
if (sparc_cpu_model != sun4d) {
- dvma_addr = (unsigned long) mmu_lockarea((char *)&risc_code01[0],
- (sizeof(u_short) * risc_code_length01));
+ dvma_addr = (unsigned long) mmu_lockarea((char *)&risc_code[0],
+ (sizeof(u_short) * risc_code_length));
param[0] = MBOX_LOAD_RAM;
- param[1] = risc_code_addr01;
+ param[1] = risc_code_addr;
param[2] = (dvma_addr >> 16);
param[3] = (dvma_addr & 0xffff);
- param[4] = (sizeof(u_short) * risc_code_length01);
+ param[4] = (sizeof(u_short) * risc_code_length);
if(qlogicpti_mbox_command(qpti, param, 1) ||
(param[0] != MBOX_COMMAND_COMPLETE)) {
printk(KERN_EMERG "qlogicpti%d: Firmware dload failed, I'm bolixed!\n",
@@ -437,14 +449,14 @@
restore_flags(flags);
return 1;
}
- mmu_unlockarea((char *)dvma_addr, (sizeof(u_short) * risc_code_length01));
+ mmu_unlockarea((char *)dvma_addr, (sizeof(u_short) * risc_code_length));
} else
#endif
/* We need to do it this slow way always on Ultra, SS[12]000. */
- for(i = 0; i < risc_code_length01; i++) {
+ for(i = 0; i < risc_code_length; i++) {
param[0] = MBOX_WRITE_RAM_WORD;
- param[1] = risc_code_addr01 + i;
- param[2] = risc_code01[i];
+ param[1] = risc_code_addr + i;
+ param[2] = risc_code[i];
if(qlogicpti_mbox_command(qpti, param, 1) ||
param[0] != MBOX_COMMAND_COMPLETE) {
printk("qlogicpti%d: Firmware dload failed, I'm bolixed!\n",
@@ -464,7 +476,7 @@
/* Ask ISP to verify the checksum of the new code. */
param[0] = MBOX_VERIFY_CHECKSUM;
- param[1] = risc_code_addr01;
+ param[1] = risc_code_addr;
if(qlogicpti_mbox_command(qpti, param, 1) ||
(param[0] != MBOX_COMMAND_COMPLETE)) {
printk(KERN_EMERG "qlogicpti%d: New firmware csum failure!\n",
@@ -475,7 +487,7 @@
/* Start using newly downloaded firmware. */
param[0] = MBOX_EXEC_FIRMWARE;
- param[1] = risc_code_addr01;
+ param[1] = risc_code_addr;
qlogicpti_mbox_command(qpti, param, 1);
param[0] = MBOX_ABOUT_FIRMWARE;
@@ -491,16 +503,18 @@
qpti->fware_majrev = param[1];
qpti->fware_minrev = param[2];
- /* Load scsi initiator ID and interrupt level into sbus static ram. */
- param[0] = MBOX_WRITE_RAM_WORD;
- param[1] = 0xff80;
- param[2] = (unsigned short) qpti->scsi_id;
- qlogicpti_mbox_command(qpti, param, 1);
-
- param[0] = MBOX_WRITE_RAM_WORD;
- param[1] = 0xff00;
- param[2] = (unsigned short) 3;
- qlogicpti_mbox_command(qpti, param, 1);
+ if(qpti->is_pti != 0) {
+ /* Load scsi initiator ID and interrupt level into sbus static ram. */
+ param[0] = MBOX_WRITE_RAM_WORD;
+ param[1] = 0xff80;
+ param[2] = (unsigned short) qpti->scsi_id;
+ qlogicpti_mbox_command(qpti, param, 1);
+
+ param[0] = MBOX_WRITE_RAM_WORD;
+ param[1] = 0xff00;
+ param[2] = (unsigned short) 3;
+ qlogicpti_mbox_command(qpti, param, 1);
+ }
restore_flags(flags);
return 0;
@@ -617,6 +631,10 @@
/* We are wide capable, 16 targets. */
qpti_host->max_id = MAX_TARGETS;
+#ifdef __sparc_v9__
+ qpti_host->unchecked_isa_dma = 1;
+#endif
+
/* Setup back pointers and misc. state. */
qpti->qhost = qpti_host;
qpti->qdev = qpti_dev;
@@ -638,7 +656,8 @@
sizeof(qpti->prom_name));
qpti->prom_node = qpti_node;
- is_pti = strcmp (qpti->prom_name, "QLGC,isp");
+ qpti->is_pti = is_pti =
+ (strcmp (qpti->prom_name, "QLGC,isp") != 0);
/* Setup the reg property for this device. */
prom_apply_sbus_ranges(qpti->qdev->my_bus,
@@ -728,6 +747,9 @@
bsizes = (DMA_BURST32 - 1);
qpti->bursts = bsizes;
+ /* Clear out Scsi_Cmnd array. */
+ memset(qpti->cmd_slots, 0, sizeof(qpti->cmd_slots));
+
/* The request and response queues must each be aligned
* on a page boundry.
*/
@@ -747,11 +769,13 @@
/* Set adapter and per-device default values. */
qlogicpti_set_hostdev_defaults(qpti);
- if (is_pti) {
- /* Load the firmware. */
- if(qlogicpti_load_firmware(qpti))
- panic("PTI Qlogic/ISP firmware load failed");
+ /* Load the firmware. */
+ /* XXX Find out where is it possible to download
+ our sbus_risc_code on non-PTI ISP1000. */
+ if(is_pti && qlogicpti_load_firmware(qpti))
+ panic("SBUS Qlogic/ISP firmware load failed");
+ if (is_pti) {
/* Check the PTI status reg. */
if(qlogicpti_verify_tmon(qpti))
panic("PTI Qlogic/ISP tmon verification failed");
@@ -768,7 +792,10 @@
char buffer[60];
prom_getstring (qpti_node, "isp-fcode", buffer, 60);
- printk("(Firmware %s)", buffer);
+ if (buffer[0])
+ printk("(Firmware %s)", buffer);
+ if (prom_getbool(qpti_node, "differential"))
+ qpti->differential = 1;
}
printk (" [%s Wide, using %s interface]\n",
@@ -831,11 +858,6 @@
memset(cmd, 0, sizeof(struct Command_Entry));
cmd->hdr.entry_cnt = 1;
cmd->hdr.entry_type = ENTRY_COMMAND;
-#ifdef __sparc_v9__
- cmd->handle = (u_int) (((unsigned long)Cmnd) - PAGE_OFFSET); /* magic mushroom */
-#else
- cmd->handle = (u_int) ((unsigned long)Cmnd); /* magic mushroom */
-#endif
cmd->target_id = Cmnd->target;
cmd->target_lun = Cmnd->lun;
cmd->cdb_length = Cmnd->cmd_len;
@@ -924,9 +946,15 @@
cmd->dataseg[0].d_count = Cmnd->request_bufflen;
cmd->segment_cnt = 1;
}
+
+ /* Committed, record Scsi_Cmd so we can find it later. */
+ cmd->handle = in_ptr;
+ qpti->cmd_slots[in_ptr] = Cmnd;
+
qpti->cmd_count[Cmnd->target]++;
qregs->mbox4 = in_ptr;
qpti->req_in_ptr = in_ptr;
+
return in_ptr;
}
@@ -1099,9 +1127,18 @@
/* This looks like a network driver! */
out_ptr = qpti->res_out_ptr;
while(out_ptr != in_ptr) {
+ u_int cmd_slot;
+
sts = (struct Status_Entry *) &qpti->res_cpu[out_ptr];
out_ptr = NEXT_RES_PTR(out_ptr);
- Cmnd = (Scsi_Cmnd *) (((unsigned long)sts->handle)+PAGE_OFFSET);
+
+ /* We store an index in the handle, not the pointer in
+ * some form. This avoids problems due to the fact
+ * that the handle provided is only 32-bits. -DaveM
+ */
+ cmd_slot = sts->handle;
+ Cmnd = qpti->cmd_slots[cmd_slot];
+ qpti->cmd_slots[cmd_slot] = NULL;
if(sts->completion_status == CS_RESET_OCCURRED ||
sts->completion_status == CS_ABORTED ||
@@ -1144,8 +1181,8 @@
int again;
spin_lock_irqsave(&io_request_lock, flags);
- again = 0;
do {
+ again = 0;
for_each_qlogicpti(qpti)
again |= qlogicpti_intr_handler(qpti);
} while (again);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)