diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1998-05-07 02:55:41 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1998-05-07 02:55:41 +0000 |
commit | dcec8a13bf565e47942a1751a9cec21bec5648fe (patch) | |
tree | 548b69625b18cc2e88c3e68d0923be546c9ebb03 /drivers/scsi/qlogicpti.c | |
parent | 2e0f55e79c49509b7ff70ff1a10e1e9e90a3dfd4 (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.c | 82 |
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 */ |