summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qlogicpti.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1998-05-07 02:55:41 +0000
committerRalf Baechle <ralf@linux-mips.org>1998-05-07 02:55:41 +0000
commitdcec8a13bf565e47942a1751a9cec21bec5648fe (patch)
tree548b69625b18cc2e88c3e68d0923be546c9ebb03 /drivers/scsi/qlogicpti.c
parent2e0f55e79c49509b7ff70ff1a10e1e9e90a3dfd4 (diff)
o Merge with Linux 2.1.99.
o Fix ancient bug in the ELF loader making ldd crash. o Fix ancient bug in the keyboard code for SGI, SNI and Jazz.
Diffstat (limited to 'drivers/scsi/qlogicpti.c')
-rw-r--r--drivers/scsi/qlogicpti.c82
1 files changed, 52 insertions, 30 deletions
diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c
index ab6c12f5c..fefbc3b45 100644
--- a/drivers/scsi/qlogicpti.c
+++ b/drivers/scsi/qlogicpti.c
@@ -31,6 +31,7 @@
#include <asm/sbus.h>
#include <asm/dma.h>
#include <asm/system.h>
+#include <asm/spinlock.h>
#include <asm/machines.h>
#include <asm/ptrace.h>
#include <asm/pgtable.h>
@@ -421,36 +422,37 @@ __initfunc(static int qlogicpti_load_firmware(struct qlogicpti *qpti))
/* Load the firmware. */
#if !defined(MODULE) && !defined(__sparc_v9__)
- dvma_addr = (unsigned long) mmu_lockarea((char *)&risc_code01[0],
- (sizeof(u_short) * risc_code_length01));
- param[0] = MBOX_LOAD_RAM;
- param[1] = risc_code_addr01;
- param[2] = (dvma_addr >> 16);
- param[3] = (dvma_addr & 0xffff);
- param[4] = (sizeof(u_short) * risc_code_length01);
- if(qlogicpti_mbox_command(qpti, param, 1) ||
- (param[0] != MBOX_COMMAND_COMPLETE)) {
- printk(KERN_EMERG "qlogicpti%d: Firmware dload failed, I'm bolixed!\n",
- qpti->qpti_id);
- restore_flags(flags);
- return 1;
- }
- mmu_unlockarea((char *)dvma_addr, (sizeof(u_short) * risc_code_length01));
-#else
- /* We need to do it this slow way always on Ultra. */
- for(i = 0; i < risc_code_length01; i++) {
- param[0] = MBOX_WRITE_RAM_WORD;
- param[1] = risc_code_addr01 + i;
- param[2] = risc_code01[i];
+ if (sparc_cpu_model != sun4d) {
+ dvma_addr = (unsigned long) mmu_lockarea((char *)&risc_code01[0],
+ (sizeof(u_short) * risc_code_length01));
+ param[0] = MBOX_LOAD_RAM;
+ param[1] = risc_code_addr01;
+ param[2] = (dvma_addr >> 16);
+ param[3] = (dvma_addr & 0xffff);
+ param[4] = (sizeof(u_short) * risc_code_length01);
if(qlogicpti_mbox_command(qpti, param, 1) ||
- param[0] != MBOX_COMMAND_COMPLETE) {
- printk("qlogicpti%d: Firmware dload failed, I'm bolixed!\n",
+ (param[0] != MBOX_COMMAND_COMPLETE)) {
+ printk(KERN_EMERG "qlogicpti%d: Firmware dload failed, I'm bolixed!\n",
qpti->qpti_id);
restore_flags(flags);
return 1;
}
- }
+ mmu_unlockarea((char *)dvma_addr, (sizeof(u_short) * risc_code_length01));
+ } else
#endif
+ /* We need to do it this slow way always on Ultra, SS[12]000. */
+ for(i = 0; i < risc_code_length01; i++) {
+ param[0] = MBOX_WRITE_RAM_WORD;
+ param[1] = risc_code_addr01 + i;
+ param[2] = risc_code01[i];
+ if(qlogicpti_mbox_command(qpti, param, 1) ||
+ param[0] != MBOX_COMMAND_COMPLETE) {
+ printk("qlogicpti%d: Firmware dload failed, I'm bolixed!\n",
+ qpti->qpti_id);
+ restore_flags(flags);
+ return 1;
+ }
+ }
/* Reset the ISP again. */
qregs->hcctrl = HCCTRL_RESET;
@@ -562,6 +564,7 @@ static inline void qlogicpti_set_hostdev_defaults(struct qlogicpti *qpti)
}
static void qlogicpti_intr_handler(int irq, void *dev_id, struct pt_regs *regs);
+static void do_qlogicpti_intr_handler(int irq, void *dev_id, struct pt_regs *regs);
/* Detect all PTI Qlogic ISP's in the machine. */
__initfunc(int qlogicpti_detect(Scsi_Host_Template *tpnt))
@@ -582,8 +585,13 @@ __initfunc(int qlogicpti_detect(Scsi_Host_Template *tpnt))
tpnt->proc_dir = &proc_scsi_qlogicpti;
qptichain = 0;
- if(!SBus_chain)
+ if(!SBus_chain) {
+#ifdef __sparc_v9__
+ return 0; /* Could be a PCI-only machine. */
+#else
panic("No SBUS in qlogicpti_detect()");
+#endif
+ }
for_each_sbus(sbus) {
for_each_sbusdev(sbdev_iter, sbus) {
qpti_dev = sbdev_iter;
@@ -669,7 +677,7 @@ __initfunc(int qlogicpti_detect(Scsi_Host_Template *tpnt))
goto qpti_irq_acquired; /* BASIC rulez */
}
}
- if(request_irq(qpti->qhost->irq, qlogicpti_intr_handler,
+ if(request_irq(qpti->qhost->irq, do_qlogicpti_intr_handler,
SA_SHIRQ, "PTI Qlogic/ISP SCSI", NULL)) {
printk("Cannot acquire PTI Qlogic/ISP irq line\n");
/* XXX Unmap regs, unregister scsi host, free things. */
@@ -685,7 +693,7 @@ qpti_irq_acquired:
dcookie.imap = dcookie.iclr = 0;
dcookie.pil = -1;
dcookie.bus_cookie = sbus;
- if(request_irq(qpti->qhost->irq, qlogicpti_intr_handler,
+ if(request_irq(qpti->qhost->irq, do_qlogicpti_intr_handler,
(SA_SHIRQ | SA_SBUS | SA_DCOOKIE),
"PTI Qlogic/ISP SCSI", &dcookie)) {
printk("Cannot acquire PTI Qlogic/ISP irq line\n");
@@ -776,8 +784,9 @@ qpti_irq_acquired:
nqptis_in_use++;
}
}
- printk("QPTI: Total of %d PTI Qlogic/ISP hosts found, %d actually in use.\n",
- nqptis, nqptis_in_use);
+ if (nqptis)
+ printk("QPTI: Total of %d PTI Qlogic/ISP hosts found, %d actually in use.\n",
+ nqptis, nqptis_in_use);
qptis_running = nqptis_in_use;
return nqptis;
}
@@ -929,7 +938,9 @@ static inline u_int load_cmd(Scsi_Cmnd *Cmnd, struct Command_Entry *cmd,
static inline void update_can_queue(struct Scsi_Host *host, u_int in_ptr, u_int out_ptr)
{
- int num_free = QLOGICISP_REQ_QUEUE_LEN - REQ_QUEUE_DEPTH(in_ptr, out_ptr);
+ /* Temporary workaround until bug is found and fixed (one bug has been found
+ already, but fixing it makes things even worse) -jj */
+ int num_free = QLOGICISP_REQ_QUEUE_LEN - REQ_QUEUE_DEPTH(in_ptr, out_ptr) - 64;
host->can_queue = host->host_busy + num_free;
host->sg_tablesize = QLOGICISP_MAX_SG(num_free);
}
@@ -1040,6 +1051,15 @@ static int qlogicpti_return_status(struct Status_Entry *sts)
return (sts->scsi_status & STATUS_MASK) | (host_status << 16);
}
+static void do_qlogicpti_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&io_request_lock, flags);
+ qlogicpti_intr_handler(irq, dev_id, regs);
+ spin_unlock_irqrestore(&io_request_lock, flags);
+}
+
#ifndef __sparc_v9__
static void qlogicpti_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
@@ -1245,4 +1265,6 @@ int qlogicpti_reset(Scsi_Cmnd *Cmnd, unsigned int reset_flags)
Scsi_Host_Template driver_template = QLOGICPTI;
#include "scsi_module.c"
+
+EXPORT_NO_SYMBOLS;
#endif /* MODULE */