Parent repository is bk://linux-scsi.bkbits.net/scsi-misc-2.6 ======== ChangeSet 1.1577 ======== D 1.1577 04/02/19 23:14:51-08:00 akpm@mnm.(none) 37129 37128 0/0/1 P ChangeSet C Merge mnm.(none):/usr/src/bk25 into mnm.(none):/usr/src/bk-scsi ------------------------------------------------ diff -Nru a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h --- a/drivers/message/fusion/mptbase.h Thu Feb 19 23:16:29 2004 +++ b/drivers/message/fusion/mptbase.h Thu Feb 19 23:16:29 2004 @@ -80,8 +80,8 @@ #define COPYRIGHT "Copyright (c) 1999-2003 " MODULEAUTHOR #endif -#define MPT_LINUX_VERSION_COMMON "3.00.02" -#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.00.02" +#define MPT_LINUX_VERSION_COMMON "3.00.03" +#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.00.03" #define WHAT_MAGIC_STRING "@" "(" "#" ")" #define show_mptmod_ver(s,ver) \ diff -Nru a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c --- a/drivers/message/fusion/mptscsih.c Thu Feb 19 23:16:29 2004 +++ b/drivers/message/fusion/mptscsih.c Thu Feb 19 23:16:29 2004 @@ -1973,7 +1973,6 @@ if (mpt_scsi_hosts > 0) return 0; - mptscsih_exit(); return -ENODEV; } diff -Nru a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig --- a/drivers/scsi/Kconfig Thu Feb 19 23:16:29 2004 +++ b/drivers/scsi/Kconfig Thu Feb 19 23:16:29 2004 @@ -23,7 +23,7 @@ config SCSI_PROC_FS bool "legacy /proc/scsi/ support" - depends on SCSI + depends on SCSI && PROC_FS default y ---help--- This option enables support for the various files in @@ -1267,28 +1267,9 @@ Note that this driver does NOT support Tekram DC390W/U/F, which are based on NCR/Symbios chips. Use "NCR53C8XX SCSI support" for those. - Also note that there is another generic Am53C974 driver, - "AM53/79C974 PCI SCSI support" below. You can pick either one. To compile this driver as a module, choose M here: the module will be called tmscsim. - -config SCSI_DC390T_NOGENSUPP - bool "_omit_ support for non-DC390 adapters" - depends on SCSI_DC390T - ---help--- - If you say N here, the DC390(T) SCSI driver relies on the DC390 - EEPROM to get initial values for its settings, such as speed, - termination, etc. If it can't find this EEPROM, it will use - defaults or the user supplied boot/module parameters. For details - on driver configuration see . - - If you say Y here and if no EEPROM is found, the driver gives up and - thus only supports Tekram DC390(T) adapters. This can be useful if - you have a DC390(T) and another Am53C974 based adapter, which, for - some reason, you want to drive with the other AM53C974 driver. - - If unsure, say N. config SCSI_T128 tristate "Trantor T128/T128F/T228 SCSI support" diff -Nru a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c --- a/drivers/scsi/NCR5380.c Thu Feb 19 23:16:29 2004 +++ b/drivers/scsi/NCR5380.c Thu Feb 19 23:16:29 2004 @@ -1326,81 +1326,71 @@ static irqreturn_t NCR5380_intr(int irq, void *dev_id, struct pt_regs *regs) { NCR5380_local_declare(); - struct Scsi_Host *instance; + struct Scsi_Host *instance = (struct Scsi_Host *)dev_id; + struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata; int done; unsigned char basr; - struct NCR5380_hostdata *hostdata; - int handled = 0; dprintk(NDEBUG_INTR, ("scsi : NCR5380 irq %d triggered\n", irq)); do { done = 1; - /* The instance list is constant while the driver is - loaded */ - for (hostdata = first_host; hostdata != NULL; hostdata = hostdata->next) - { - instance = hostdata->host; - if (instance->irq == irq) { - handled = 1; - spin_lock_irq(instance->host_lock); - /* Look for pending interrupts */ - NCR5380_setup(instance); - basr = NCR5380_read(BUS_AND_STATUS_REG); - /* XXX dispatch to appropriate routine if found and done=0 */ - if (basr & BASR_IRQ) { - NCR5380_dprint(NDEBUG_INTR, instance); - if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) == (SR_SEL | SR_IO)) { - done = 0; - dprintk(NDEBUG_INTR, ("scsi%d : SEL interrupt\n", instance->host_no)); - NCR5380_reselect(instance); - (void) NCR5380_read(RESET_PARITY_INTERRUPT_REG); - } else if (basr & BASR_PARITY_ERROR) { - dprintk(NDEBUG_INTR, ("scsi%d : PARITY interrupt\n", instance->host_no)); - (void) NCR5380_read(RESET_PARITY_INTERRUPT_REG); - } else if ((NCR5380_read(STATUS_REG) & SR_RST) == SR_RST) { - dprintk(NDEBUG_INTR, ("scsi%d : RESET interrupt\n", instance->host_no)); - (void) NCR5380_read(RESET_PARITY_INTERRUPT_REG); - } else { + spin_lock_irq(instance->host_lock); + /* Look for pending interrupts */ + NCR5380_setup(instance); + basr = NCR5380_read(BUS_AND_STATUS_REG); + /* XXX dispatch to appropriate routine if found and done=0 */ + if (basr & BASR_IRQ) { + NCR5380_dprint(NDEBUG_INTR, instance); + if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) == (SR_SEL | SR_IO)) { + done = 0; + dprintk(NDEBUG_INTR, ("scsi%d : SEL interrupt\n", instance->host_no)); + NCR5380_reselect(instance); + (void) NCR5380_read(RESET_PARITY_INTERRUPT_REG); + } else if (basr & BASR_PARITY_ERROR) { + dprintk(NDEBUG_INTR, ("scsi%d : PARITY interrupt\n", instance->host_no)); + (void) NCR5380_read(RESET_PARITY_INTERRUPT_REG); + } else if ((NCR5380_read(STATUS_REG) & SR_RST) == SR_RST) { + dprintk(NDEBUG_INTR, ("scsi%d : RESET interrupt\n", instance->host_no)); + (void) NCR5380_read(RESET_PARITY_INTERRUPT_REG); + } else { #if defined(REAL_DMA) - /* - * We should only get PHASE MISMATCH and EOP interrupts - * if we have DMA enabled, so do a sanity check based on - * the current setting of the MODE register. - */ - - if ((NCR5380_read(MODE_REG) & MR_DMA) && ((basr & BASR_END_DMA_TRANSFER) || !(basr & BASR_PHASE_MATCH))) { - int transfered; - - if (!hostdata->connected) - panic("scsi%d : received end of DMA interrupt with no connected cmd\n", instance->hostno); - - transfered = (hostdata->dmalen - NCR5380_dma_residual(instance)); - hostdata->connected->SCp.this_residual -= transferred; - hostdata->connected->SCp.ptr += transferred; - hostdata->dmalen = 0; + /* + * We should only get PHASE MISMATCH and EOP interrupts + * if we have DMA enabled, so do a sanity check based on + * the current setting of the MODE register. + */ + + if ((NCR5380_read(MODE_REG) & MR_DMA) && ((basr & BASR_END_DMA_TRANSFER) || !(basr & BASR_PHASE_MATCH))) { + int transfered; + + if (!hostdata->connected) + panic("scsi%d : received end of DMA interrupt with no connected cmd\n", instance->hostno); + + transfered = (hostdata->dmalen - NCR5380_dma_residual(instance)); + hostdata->connected->SCp.this_residual -= transferred; + hostdata->connected->SCp.ptr += transferred; + hostdata->dmalen = 0; - (void) NCR5380_read(RESET_PARITY_INTERRUPT_REG); + (void) NCR5380_read(RESET_PARITY_INTERRUPT_REG); - /* FIXME: we need to poll briefly then defer a workqueue task ! */ - NCR5380_poll_politely(hostdata, BUS_AND_STATUS_REG, BASR_ACK, 0, 2*HZ); + /* FIXME: we need to poll briefly then defer a workqueue task ! */ + NCR5380_poll_politely(hostdata, BUS_AND_STATUS_REG, BASR_ACK, 0, 2*HZ); - NCR5380_write(MODE_REG, MR_BASE); - NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); - } + NCR5380_write(MODE_REG, MR_BASE); + NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); + } #else - dprintk(NDEBUG_INTR, ("scsi : unknown interrupt, BASR 0x%X, MR 0x%X, SR 0x%x\n", basr, NCR5380_read(MODE_REG), NCR5380_read(STATUS_REG))); - (void) NCR5380_read(RESET_PARITY_INTERRUPT_REG); + dprintk(NDEBUG_INTR, ("scsi : unknown interrupt, BASR 0x%X, MR 0x%X, SR 0x%x\n", basr, NCR5380_read(MODE_REG), NCR5380_read(STATUS_REG))); + (void) NCR5380_read(RESET_PARITY_INTERRUPT_REG); #endif - } - } /* if BASR_IRQ */ - spin_unlock_irq(instance->host_lock); - if(!done) - schedule_work(&hostdata->coroutine); - } /* if (instance->irq == irq) */ - } + } + } /* if BASR_IRQ */ + spin_unlock_irq(instance->host_lock); + if(!done) + schedule_work(&hostdata->coroutine); } while (!done); - return IRQ_RETVAL(handled); + return IRQ_HANDLED; } #endif diff -Nru a/drivers/scsi/aacraid/Makefile b/drivers/scsi/aacraid/Makefile --- a/drivers/scsi/aacraid/Makefile Thu Feb 19 23:16:29 2004 +++ b/drivers/scsi/aacraid/Makefile Thu Feb 19 23:16:29 2004 @@ -3,6 +3,6 @@ obj-$(CONFIG_SCSI_AACRAID) := aacraid.o aacraid-objs := linit.o aachba.o commctrl.o comminit.o commsup.o \ - dpcsup.o rx.o sa.o + dpcsup.o rx.o sa.o rkt.o EXTRA_CFLAGS := -Idrivers/scsi diff -Nru a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h --- a/drivers/scsi/aacraid/aacraid.h Thu Feb 19 23:16:29 2004 +++ b/drivers/scsi/aacraid/aacraid.h Thu Feb 19 23:16:29 2004 @@ -713,6 +713,24 @@ #define rx_writeb(AEP, CSR, value) writeb(value, &((AEP)->regs.rx->CSR)) #define rx_writel(AEP, CSR, value) writel(value, &((AEP)->regs.rx->CSR)) +/* + * Rkt Message Unit Registers (same as Rx, except a larger reserve region) + */ + +#define rkt_mu_registers rx_mu_registers +#define rkt_inbound rx_inbound + +struct rkt_registers { + struct rkt_mu_registers MUnit; /* 1300h - 1334h */ + u32 reserved1[1010]; /* 1338h - 22fch */ + struct rkt_inbound IndexRegs; /* 2300h - */ +}; + +#define rkt_readb(AEP, CSR) readb(&((AEP)->regs.rkt->CSR)) +#define rkt_readl(AEP, CSR) readl(&((AEP)->regs.rkt->CSR)) +#define rkt_writeb(AEP, CSR, value) writeb(value, &((AEP)->regs.rkt->CSR)) +#define rkt_writel(AEP, CSR, value) writel(value, &((AEP)->regs.rkt->CSR)) + struct fib; typedef void (*fib_callback)(void *ctxt, struct fib *fibctx); @@ -889,7 +907,9 @@ { struct sa_registers *sa; struct rx_registers *rx; + struct rkt_registers *rkt; } regs; + u32 OIMR; /* Mask Register Cache */ /* * The following is the number of the individual adapter */ @@ -1492,6 +1512,7 @@ int aac_dev_ioctl(struct aac_dev *dev, int cmd, void *arg); int aac_do_ioctl(struct aac_dev * dev, int cmd, void *arg); int aac_rx_init(struct aac_dev *dev, unsigned long devNumber); +int aac_rkt_init(struct aac_dev *dev, unsigned long devNumber); int aac_sa_init(struct aac_dev *dev, unsigned long devNumber); unsigned int aac_response_normal(struct aac_queue * q); unsigned int aac_command_normal(struct aac_queue * q); diff -Nru a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c --- a/drivers/scsi/aacraid/linit.c Thu Feb 19 23:16:29 2004 +++ b/drivers/scsi/aacraid/linit.c Thu Feb 19 23:16:29 2004 @@ -101,14 +101,20 @@ { 0x9005, 0x0285, 0x9005, 0x028a, 0, 0, 18 }, /* ASR-2020S PCI-X ZCR (Skyhawk)*/ { 0x9005, 0x0285, 0x9005, 0x028b, 0, 0, 19 }, /* ASR-2020S SO-DIMM PCI-X ZCR(Terminator)*/ { 0x9005, 0x0285, 0x9005, 0x0290, 0, 0, 20 }, /* AAR-2410SA PCI SATA 4ch (Jaguar II)*/ - { 0x9005, 0x0250, 0x1014, 0x0279, 0, 0, 21 }, /* (Marco)*/ - { 0x9005, 0x0250, 0x1014, 0x028c, 0, 0, 22 }, /* (Sebring)*/ - { 0x9005, 0x0285, 0x1028, 0x0287, 0, 0, 23 }, /* Perc 320/DC*/ - { 0x1011, 0x0046, 0x9005, 0x0365, 0, 0, 24 }, /* Adaptec 5400S (Mustang)*/ - { 0x1011, 0x0046, 0x9005, 0x0364, 0, 0, 25 }, /* Adaptec 5400S (Mustang)*/ - { 0x1011, 0x0046, 0x9005, 0x1364, 0, 0, 26 }, /* Dell PERC2 "Quad Channel" */ - { 0x1011, 0x0046, 0x103c, 0x10c2, 0, 0, 27 }, /* HP NetRAID-4M */ + { 0x9005, 0x0285, 0x1028, 0x0287, 0, 0, 21 }, /* Perc 320/DC*/ + { 0x1011, 0x0046, 0x9005, 0x0365, 0, 0, 22 }, /* Adaptec 5400S (Mustang)*/ + { 0x1011, 0x0046, 0x9005, 0x0364, 0, 0, 23 }, /* Adaptec 5400S (Mustang)*/ + { 0x1011, 0x0046, 0x9005, 0x1364, 0, 0, 24 }, /* Dell PERC2 "Quad Channel" */ + { 0x1011, 0x0046, 0x103c, 0x10c2, 0, 0, 25 }, /* HP NetRAID-4M */ + + { 0x9005, 0x0285, 0x1028, 0x0291, 0, 0, 26 }, /* CERC SATA RAID 2 PCI SATA 6ch (DellCorsair) */ + { 0x9005, 0x0285, 0x9005, 0x0292, 0, 0, 27 }, /* AAR-2810SA PCI SATA 8ch (Corsair-8) */ + { 0x9005, 0x0285, 0x9005, 0x0293, 0, 0, 28 }, /* AAR-21610SA PCI SATA 16ch (Corsair-16) */ + { 0x9005, 0x0285, 0x9005, 0x0294, 0, 0, 29 }, /* ESD SO-DIMM PCI-X SATA ZCR (Prowler) */ + { 0x9005, 0x0285, 0x0E11, 0x0295, 0, 0, 30 }, /* SATA 6Ch (Bearcat) */ + + { 0x9005, 0x0286, 0x9005, 0x028c, 0, 0, 31 }, /* ASR-2230S + ASR-2230SLP PCI-X (Lancer) */ { 0,} }; MODULE_DEVICE_TABLE(pci, aac_pci_tbl); @@ -141,14 +147,20 @@ { aac_rx_init, "aacraid", "ADAPTEC ", "ASR-2020S PCI-X ", 2 }, /* ASR-2020S PCI-X ZCR (Skyhawk)*/ { aac_rx_init, "aacraid", "ADAPTEC ", "ASR-2020S PCI-X ", 2 }, /* ASR-2020S SO-DIMM PCI-X ZCR(Terminator)*/ { aac_rx_init, "aacraid", "ADAPTEC ", "AAR-2410SA SATA ", 2 }, /* AAR-2410SA PCI SATA 4ch (Jaguar II)*/ - { aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec ", 2 }, /* (Marco)*/ - { aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec ", 2 }, /* (Sebring)*/ { aac_rx_init, "percraid", "DELL ", "PERC 320/DC ", 2, AAC_QUIRK_31BIT }, /* Perc 320/DC*/ { aac_sa_init, "aacraid", "ADAPTEC ", "Adaptec 5400S ", 4 }, /* Adaptec 5400S (Mustang)*/ { aac_sa_init, "aacraid", "ADAPTEC ", "AAC-364 ", 4 }, /* Adaptec 5400S (Mustang)*/ { aac_sa_init, "percraid", "DELL ", "PERCRAID ", 4, AAC_QUIRK_31BIT }, /* Dell PERC2 "Quad Channel" */ - { aac_sa_init, "hpnraid", "HP ", "NetRAID ", 4 } /* HP NetRAID-4M */ + { aac_sa_init, "hpnraid", "HP ", "NetRAID ", 4 }, /* HP NetRAID-4M */ + + { aac_rx_init, "aacraid", "DELL ", "CERC SR2 ", 1 }, /* CERC SATA RAID 2 PCI SATA 6ch (DellCorsair) */ + { aac_rx_init, "aacraid", "ADAPTEC ", "AAR-2810SA SATA ", 1 }, /* AAR-2810SA PCI SATA 8ch (Corsair-8) */ + { aac_rx_init, "aacraid", "ADAPTEC ", "AAR-21610SA SATA", 1 }, /* AAR-21610SA PCI SATA 16ch (Corsair-16) */ + { aac_rx_init, "aacraid", "ADAPTEC ", "SO-DIMM SATA ZCR", 1 }, /* ESD SO-DIMM PCI-X SATA ZCR (Prowler) */ + { aac_rx_init, "aacraid", "ADAPTEC ", "SATA 6Channel ", 1 }, /* SATA 6Ch (Bearcat) */ + + { aac_rkt_init,"aacraid", "ADAPTEC ", "ASR-2230S PCI-X ", 2 }, /* ASR-2230S + ASR-2230SLP PCI-X (Lancer) */ }; /** diff -Nru a/drivers/scsi/aacraid/rkt.c b/drivers/scsi/aacraid/rkt.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/scsi/aacraid/rkt.c Thu Feb 19 23:16:29 2004 @@ -0,0 +1,416 @@ +/* + * Adaptec AAC series RAID controller driver + * (c) Copyright 2001 Red Hat Inc. + * + * based on the old aacraid driver that is.. + * Adaptec aacraid device driver for Linux. + * + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Module Name: + * rkt.c + * + * Abstract: Hardware miniport for Drawbridge specific hardware functions. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "aacraid.h" + +static irqreturn_t aac_rkt_intr(int irq, void *dev_id, struct pt_regs *regs) +{ + struct aac_dev *dev = dev_id; + unsigned long bellbits; + u8 intstat, mask; + intstat = rkt_readb(dev, MUnit.OISR); + /* + * Read mask and invert because drawbridge is reversed. + * This allows us to only service interrupts that have + * been enabled. + */ + mask = ~(dev->OIMR); + /* Check to see if this is our interrupt. If it isn't just return */ + if (intstat & mask) + { + bellbits = rkt_readl(dev, OutboundDoorbellReg); + if (bellbits & DoorBellPrintfReady) { + aac_printf(dev, le32_to_cpu(rkt_readl (dev, IndexRegs.Mailbox[5]))); + rkt_writel(dev, MUnit.ODR,DoorBellPrintfReady); + rkt_writel(dev, InboundDoorbellReg,DoorBellPrintfDone); + } + else if (bellbits & DoorBellAdapterNormCmdReady) { + aac_command_normal(&dev->queues->queue[HostNormCmdQueue]); + rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdReady); + } + else if (bellbits & DoorBellAdapterNormRespReady) { + aac_response_normal(&dev->queues->queue[HostNormRespQueue]); + rkt_writel(dev, MUnit.ODR,DoorBellAdapterNormRespReady); + } + else if (bellbits & DoorBellAdapterNormCmdNotFull) { + rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull); + } + else if (bellbits & DoorBellAdapterNormRespNotFull) { + rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull); + rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormRespNotFull); + } + return IRQ_HANDLED; + } + return IRQ_NONE; +} + +/** + * aac_rkt_enable_interrupt - Enable event reporting + * @dev: Adapter + * @event: Event to enable + * + * Enable event reporting from the i960 for a given event. + */ + +static void aac_rkt_enable_interrupt(struct aac_dev * dev, u32 event) +{ + switch (event) { + + case HostNormCmdQue: + dev->irq_mask &= ~(OUTBOUNDDOORBELL_1); + break; + + case HostNormRespQue: + dev->irq_mask &= ~(OUTBOUNDDOORBELL_2); + break; + + case AdapNormCmdNotFull: + dev->irq_mask &= ~(OUTBOUNDDOORBELL_3); + break; + + case AdapNormRespNotFull: + dev->irq_mask &= ~(OUTBOUNDDOORBELL_4); + break; + } +} + +/** + * aac_rkt_disable_interrupt - Disable event reporting + * @dev: Adapter + * @event: Event to enable + * + * Disable event reporting from the i960 for a given event. + */ + +static void aac_rkt_disable_interrupt(struct aac_dev *dev, u32 event) +{ + switch (event) { + + case HostNormCmdQue: + dev->irq_mask |= (OUTBOUNDDOORBELL_1); + break; + + case HostNormRespQue: + dev->irq_mask |= (OUTBOUNDDOORBELL_2); + break; + + case AdapNormCmdNotFull: + dev->irq_mask |= (OUTBOUNDDOORBELL_3); + break; + + case AdapNormRespNotFull: + dev->irq_mask |= (OUTBOUNDDOORBELL_4); + break; + } +} + +/** + * rkt_sync_cmd - send a command and wait + * @dev: Adapter + * @command: Command to execute + * @p1: first parameter + * @ret: adapter status + * + * This routine will send a synchronous comamnd to the adapter and wait + * for its completion. + */ + +static int rkt_sync_cmd(struct aac_dev *dev, u32 command, u32 p1, u32 *status) +{ + unsigned long start; + int ok; + /* + * Write the command into Mailbox 0 + */ + rkt_writel(dev, InboundMailbox0, cpu_to_le32(command)); + /* + * Write the parameters into Mailboxes 1 - 4 + */ + rkt_writel(dev, InboundMailbox1, cpu_to_le32(p1)); + rkt_writel(dev, InboundMailbox2, 0); + rkt_writel(dev, InboundMailbox3, 0); + rkt_writel(dev, InboundMailbox4, 0); + /* + * Clear the synch command doorbell to start on a clean slate. + */ + rkt_writel(dev, OutboundDoorbellReg, OUTBOUNDDOORBELL_0); + /* + * Disable doorbell interrupts + */ + rkt_writeb(dev, MUnit.OIMR, dev->OIMR |= 0x04); + /* + * Force the completion of the mask register write before issuing + * the interrupt. + */ + rkt_readb (dev, MUnit.OIMR); + /* + * Signal that there is a new synch command + */ + rkt_writel(dev, InboundDoorbellReg, INBOUNDDOORBELL_0); + + ok = 0; + start = jiffies; + + /* + * Wait up to 30 seconds + */ + while (time_before(jiffies, start+30*HZ)) + { + udelay(5); /* Delay 5 microseconds to let Mon960 get info. */ + /* + * Mon960 will set doorbell0 bit when it has completed the command. + */ + if (rkt_readl(dev, OutboundDoorbellReg) & OUTBOUNDDOORBELL_0) { + /* + * Clear the doorbell. + */ + rkt_writel(dev, OutboundDoorbellReg, OUTBOUNDDOORBELL_0); + ok = 1; + break; + } + /* + * Yield the processor in case we are slow + */ + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(1); + } + if (ok != 1) { + /* + * Restore interrupt mask even though we timed out + */ + rkt_writeb(dev, MUnit.OIMR, dev->OIMR &= 0xfb); + return -ETIMEDOUT; + } + /* + * Pull the synch status from Mailbox 0. + */ + *status = le32_to_cpu(rkt_readl(dev, IndexRegs.Mailbox[0])); + /* + * Clear the synch command doorbell. + */ + rkt_writel(dev, OutboundDoorbellReg, OUTBOUNDDOORBELL_0); + /* + * Restore interrupt mask + */ + rkt_writeb(dev, MUnit.OIMR, dev->OIMR &= 0xfb); + return 0; + +} + +/** + * aac_rkt_interrupt_adapter - interrupt adapter + * @dev: Adapter + * + * Send an interrupt to the i960 and breakpoint it. + */ + +static void aac_rkt_interrupt_adapter(struct aac_dev *dev) +{ + u32 ret; + rkt_sync_cmd(dev, BREAKPOINT_REQUEST, 0, &ret); +} + +/** + * aac_rkt_notify_adapter - send an event to the adapter + * @dev: Adapter + * @event: Event to send + * + * Notify the i960 that something it probably cares about has + * happened. + */ + +static void aac_rkt_notify_adapter(struct aac_dev *dev, u32 event) +{ + switch (event) { + + case AdapNormCmdQue: + rkt_writel(dev, MUnit.IDR,INBOUNDDOORBELL_1); + break; + case HostNormRespNotFull: + rkt_writel(dev, MUnit.IDR,INBOUNDDOORBELL_4); + break; + case AdapNormRespQue: + rkt_writel(dev, MUnit.IDR,INBOUNDDOORBELL_2); + break; + case HostNormCmdNotFull: + rkt_writel(dev, MUnit.IDR,INBOUNDDOORBELL_3); + break; + case HostShutdown: +// rkt_sync_cmd(dev, HOST_CRASHING, 0, 0, 0, 0, &ret); + break; + case FastIo: + rkt_writel(dev, MUnit.IDR,INBOUNDDOORBELL_6); + break; + case AdapPrintfDone: + rkt_writel(dev, MUnit.IDR,INBOUNDDOORBELL_5); + break; + default: + BUG(); + break; + } +} + +/** + * aac_rkt_start_adapter - activate adapter + * @dev: Adapter + * + * Start up processing on an i960 based AAC adapter + */ + +static void aac_rkt_start_adapter(struct aac_dev *dev) +{ + u32 status; + struct aac_init *init; + + init = dev->init; + init->HostElapsedSeconds = cpu_to_le32(jiffies/HZ); + /* + * Tell the adapter we are back and up and running so it will scan + * its command queues and enable our interrupts + */ + dev->irq_mask = (DoorBellPrintfReady | OUTBOUNDDOORBELL_1 | OUTBOUNDDOORBELL_2 | OUTBOUNDDOORBELL_3 | OUTBOUNDDOORBELL_4); + /* + * First clear out all interrupts. Then enable the one's that we + * can handle. + */ + rkt_writeb(dev, MUnit.OIMR, 0xff); + rkt_writel(dev, MUnit.ODR, 0xffffffff); +// rkt_writeb(dev, MUnit.OIMR, ~(u8)OUTBOUND_DOORBELL_INTERRUPT_MASK); + rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb); + + // We can only use a 32 bit address here + rkt_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, (u32)(ulong)dev->init_pa, &status); +} + +/** + * aac_rkt_init - initialize an i960 based AAC card + * @dev: device to configure + * @devnum: adapter number + * + * Allocate and set up resources for the i960 based AAC variants. The + * device_interface in the commregion will be allocated and linked + * to the comm region. + */ + +int aac_rkt_init(struct aac_dev *dev, unsigned long num) +{ + unsigned long start; + unsigned long status; + int instance; + const char * name; + + dev->devnum = num; + instance = dev->id; + name = dev->name; + + /* + * Map in the registers from the adapter. + */ + if((dev->regs.rkt = (struct rkt_registers *)ioremap((unsigned long)dev->scsi_host_ptr->base, 8192))==NULL) + { + printk(KERN_WARNING "aacraid: unable to map i960.\n" ); + return -1; + } + /* + * Check to see if the board failed any self tests. + */ + if (rkt_readl(dev, IndexRegs.Mailbox[7]) & SELF_TEST_FAILED) { + printk(KERN_ERR "%s%d: adapter self-test failed.\n", dev->name, instance); + return -1; + } + /* + * Check to see if the board panic'd while booting. + */ + if (rkt_readl(dev, IndexRegs.Mailbox[7]) & KERNEL_PANIC) { + printk(KERN_ERR "%s%d: adapter kernel panic'd.\n", dev->name, instance); + return -1; + } + start = jiffies; + /* + * Wait for the adapter to be up and running. Wait up to 3 minutes + */ + while (!(rkt_readl(dev, IndexRegs.Mailbox[7]) & KERNEL_UP_AND_RUNNING)) + { + if(time_after(jiffies, start+180*HZ)) + { + status = rkt_readl(dev, IndexRegs.Mailbox[7]) >> 16; + printk(KERN_ERR "%s%d: adapter kernel failed to start, init status = %ld.\n", dev->name, instance, status); + return -1; + } + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(1); + } + if (request_irq(dev->scsi_host_ptr->irq, aac_rkt_intr, SA_SHIRQ|SA_INTERRUPT, "aacraid", (void *)dev)<0) + { + printk(KERN_ERR "%s%d: Interrupt unavailable.\n", name, instance); + return -1; + } + /* + * Fill in the function dispatch table. + */ + dev->a_ops.adapter_interrupt = aac_rkt_interrupt_adapter; + dev->a_ops.adapter_enable_int = aac_rkt_enable_interrupt; + dev->a_ops.adapter_disable_int = aac_rkt_disable_interrupt; + dev->a_ops.adapter_notify = aac_rkt_notify_adapter; + dev->a_ops.adapter_sync_cmd = rkt_sync_cmd; + + if (aac_init_adapter(dev) == NULL) + return -1; + /* + * Start any kernel threads needed + */ + dev->thread_pid = kernel_thread((int (*)(void *))aac_command_thread, dev, 0); + if(dev->thread_pid < 0) + { + printk(KERN_ERR "aacraid: Unable to create rkt thread.\n"); + return -1; + } + /* + * Tell the adapter that all is configured, and it can start + * accepting requests + */ + aac_rkt_start_adapter(dev); + return 0; +} diff -Nru a/drivers/scsi/aacraid/rkt.c-old b/drivers/scsi/aacraid/rkt.c-old --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/scsi/aacraid/rkt.c-old Thu Feb 19 23:16:29 2004 @@ -0,0 +1,416 @@ +/* + * Adaptec AAC series RAID controller driver + * (c) Copyright 2001 Red Hat Inc. + * + * based on the old aacraid driver that is.. + * Adaptec aacraid device driver for Linux. + * + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Module Name: + * rkt.c + * + * Abstract: Hardware miniport for Drawbridge specific hardware functions. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "aacraid.h" + +static irqreturn_t aac_rkt_intr(int irq, void *dev_id, struct pt_regs *regs) +{ + struct aac_dev *dev = dev_id; + unsigned long bellbits; + u8 intstat, mask; + intstat = rkt_readb(dev, MUnit.OISR); + /* + * Read mask and invert because drawbridge is reversed. + * This allows us to only service interrupts that have + * been enabled. + */ + mask = ~(dev->OIMR); + /* Check to see if this is our interrupt. If it isn't just return */ + if (intstat & mask) + { + bellbits = rkt_readl(dev, OutboundDoorbellReg); + if (bellbits & DoorBellPrintfReady) { + aac_printf(dev, le32_to_cpu(rkt_readl (dev, IndexRegs.Mailbox[5]))); + rkt_writel(dev, MUnit.ODR,DoorBellPrintfReady); + rkt_writel(dev, InboundDoorbellReg,DoorBellPrintfDone); + } + else if (bellbits & DoorBellAdapterNormCmdReady) { + aac_command_normal(&dev->queues->queue[HostNormCmdQueue]); + rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdReady); + } + else if (bellbits & DoorBellAdapterNormRespReady) { + aac_response_normal(&dev->queues->queue[HostNormRespQueue]); + rkt_writel(dev, MUnit.ODR,DoorBellAdapterNormRespReady); + } + else if (bellbits & DoorBellAdapterNormCmdNotFull) { + rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull); + } + else if (bellbits & DoorBellAdapterNormRespNotFull) { + rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull); + rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormRespNotFull); + } + return IRQ_HANDLED; + } + return IRQ_NONE; +} + +/** + * aac_rkt_enable_interrupt - Enable event reporting + * @dev: Adapter + * @event: Event to enable + * + * Enable event reporting from the i960 for a given event. + */ + +static void aac_rkt_enable_interrupt(struct aac_dev * dev, u32 event) +{ + switch (event) { + + case HostNormCmdQue: + dev->irq_mask &= ~(OUTBOUNDDOORBELL_1); + break; + + case HostNormRespQue: + dev->irq_mask &= ~(OUTBOUNDDOORBELL_2); + break; + + case AdapNormCmdNotFull: + dev->irq_mask &= ~(OUTBOUNDDOORBELL_3); + break; + + case AdapNormRespNotFull: + dev->irq_mask &= ~(OUTBOUNDDOORBELL_4); + break; + } +} + +/** + * aac_rkt_disable_interrupt - Disable event reporting + * @dev: Adapter + * @event: Event to enable + * + * Disable event reporting from the i960 for a given event. + */ + +static void aac_rkt_disable_interrupt(struct aac_dev *dev, u32 event) +{ + switch (event) { + + case HostNormCmdQue: + dev->irq_mask |= (OUTBOUNDDOORBELL_1); + break; + + case HostNormRespQue: + dev->irq_mask |= (OUTBOUNDDOORBELL_2); + break; + + case AdapNormCmdNotFull: + dev->irq_mask |= (OUTBOUNDDOORBELL_3); + break; + + case AdapNormRespNotFull: + dev->irq_mask |= (OUTBOUNDDOORBELL_4); + break; + } +} + +/** + * rkt_sync_cmd - send a command and wait + * @dev: Adapter + * @command: Command to execute + * @p1: first parameter + * @ret: adapter status + * + * This routine will send a synchronous comamnd to the adapter and wait + * for its completion. + */ + +static int rkt_sync_cmd(struct aac_dev *dev, u32 command, u32 p1, u32 *status) +{ + unsigned long start; + int ok; + /* + * Write the command into Mailbox 0 + */ + rkt_writel(dev, InboundMailbox0, cpu_to_le32(command)); + /* + * Write the parameters into Mailboxes 1 - 4 + */ + rkt_writel(dev, InboundMailbox1, cpu_to_le32(p1)); + rkt_writel(dev, InboundMailbox2, 0); + rkt_writel(dev, InboundMailbox3, 0); + rkt_writel(dev, InboundMailbox4, 0); + /* + * Clear the synch command doorbell to start on a clean slate. + */ + rkt_writel(dev, OutboundDoorbellReg, OUTBOUNDDOORBELL_0); + /* + * Disable doorbell interrupts + */ + rkt_writeb(dev, MUnit.OIMR, dev->OIMR |= 0x04); + /* + * Force the completion of the mask register write before issuing + * the interrupt. + */ + rkt_readb (dev, MUnit.OIMR); + /* + * Signal that there is a new synch command + */ + rkt_writel(dev, InboundDoorbellReg, INBOUNDDOORBELL_0); + + ok = 0; + start = jiffies; + + /* + * Wait up to 30 seconds + */ + while (time_before(jiffies, start+30*HZ)) + { + udelay(5); /* Delay 5 microseconds to let Mon960 get info. */ + /* + * Mon960 will set doorbell0 bit when it has completed the command. + */ + if (rkt_readl(dev, OutboundDoorbellReg) & OUTBOUNDDOORBELL_0) { + /* + * Clear the doorbell. + */ + rkt_writel(dev, OutboundDoorbellReg, OUTBOUNDDOORBELL_0); + ok = 1; + break; + } + /* + * Yield the processor in case we are slow + */ + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(1); + } + if (ok != 1) { + /* + * Restore interrupt mask even though we timed out + */ + rkt_writeb(dev, MUnit.OIMR, dev->OIMR &= 0xfb); + return -ETIMEDOUT; + } + /* + * Pull the synch status from Mailbox 0. + */ + *status = le32_to_cpu(rkt_readl(dev, IndexRegs.Mailbox[0])); + /* + * Clear the synch command doorbell. + */ + rkt_writel(dev, OutboundDoorbellReg, OUTBOUNDDOORBELL_0); + /* + * Restore interrupt mask + */ + rkt_writeb(dev, MUnit.OIMR, dev->OIMR &= 0xfb); + return 0; + +} + +/** + * aac_rkt_interrupt_adapter - interrupt adapter + * @dev: Adapter + * + * Send an interrupt to the i960 and breakpoint it. + */ + +static void aac_rkt_interrupt_adapter(struct aac_dev *dev) +{ + u32 ret; + rkt_sync_cmd(dev, BREAKPOINT_REQUEST, 0, &ret); +} + +/** + * aac_rkt_notify_adapter - send an event to the adapter + * @dev: Adapter + * @event: Event to send + * + * Notify the i960 that something it probably cares about has + * happened. + */ + +static void aac_rkt_notify_adapter(struct aac_dev *dev, u32 event) +{ + switch (event) { + + case AdapNormCmdQue: + rkt_writel(dev, MUnit.IDR,INBOUNDDOORBELL_1); + break; + case HostNormRespNotFull: + rkt_writel(dev, MUnit.IDR,INBOUNDDOORBELL_4); + break; + case AdapNormRespQue: + rkt_writel(dev, MUnit.IDR,INBOUNDDOORBELL_2); + break; + case HostNormCmdNotFull: + rkt_writel(dev, MUnit.IDR,INBOUNDDOORBELL_3); + break; + case HostShutdown: +// rkt_sync_cmd(dev, HOST_CRASHING, 0, 0, 0, 0, &ret); + break; + case FastIo: + rkt_writel(dev, MUnit.IDR,INBOUNDDOORBELL_6); + break; + case AdapPrintfDone: + rkt_writel(dev, MUnit.IDR,INBOUNDDOORBELL_5); + break; + default: + BUG(); + break; + } +} + +/** + * aac_rkt_start_adapter - activate adapter + * @dev: Adapter + * + * Start up processing on an i960 based AAC adapter + */ + +static void aac_rkt_start_adapter(struct aac_dev *dev) +{ + u32 status; + struct aac_init *init; + + init = dev->init; + init->HostElapsedSeconds = cpu_to_le32(jiffies/HZ); + /* + * Tell the adapter we are back and up and running so it will scan + * its command queues and enable our interrupts + */ + dev->irq_mask = (DoorBellPrintfReady | OUTBOUNDDOORBELL_1 | OUTBOUNDDOORBELL_2 | OUTBOUNDDOORBELL_3 | OUTBOUNDDOORBELL_4); + /* + * First clear out all interrupts. Then enable the one's that we + * can handle. + */ + rkt_writeb(dev, MUnit.OIMR, 0xff); + rkt_writel(dev, MUnit.ODR, 0xffffffff); +// rkt_writeb(dev, MUnit.OIMR, ~(u8)OUTBOUND_DOORBELL_INTERRUPT_MASK); + rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb); + + // We can only use a 32 bit address here + rkt_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, (u32)(ulong)dev->init_pa, &status); +} + +/** + * aac_rkt_init - initialize an i960 based AAC card + * @dev: device to configure + * @devnum: adapter number + * + * Allocate and set up resources for the i960 based AAC variants. The + * device_interface in the commregion will be allocated and linked + * to the comm region. + */ + +int aac_rkt_init(struct aac_dev *dev, unsigned long num) +{ + unsigned long start; + unsigned long status; + int instance; + const char * name; + + dev->devnum = num; + instance = dev->id; + name = dev->name; + + /* + * Map in the registers from the adapter. + */ + if((dev->regs.rkt = (struct rkt_registers *)ioremap((unsigned long)dev->scsi_host_ptr->base, 8192))==NULL) + { + printk(KERN_WARNING "aacraid: unable to map i960.\n" ); + return -1; + } + /* + * Check to see if the board failed any self tests. + */ + if (rkt_readl(dev, IndexRegs.Mailbox[7]) & SELF_TEST_FAILED) { + printk(KERN_ERR "%s%d: adapter self-test failed.\n", dev->name, instance); + return -1; + } + /* + * Check to see if the board panic'd while booting. + */ + if (rkt_readl(dev, IndexRegs.Mailbox[7]) & KERNEL_PANIC) { + printk(KERN_ERR "%s%d: adapter kernel panic'd.\n", dev->name, instance); + return -1; + } + start = jiffies; + /* + * Wait for the adapter to be up and running. Wait up to 3 minutes + */ + while (!(rkt_readl(dev, IndexRegs.Mailbox[7]) & KERNEL_UP_AND_RUNNING)) + { + if(time_after(jiffies, start+180*HZ)) + { + status = rkt_readl(dev, IndexRegs.Mailbox[7]) >> 16; + printk(KERN_ERR "%s%d: adapter kernel failed to start, init status = %ld.\n", dev->name, instance, status); + return -1; + } + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(1); + } + if (request_irq(dev->scsi_host_ptr->irq, aac_rkt_intr, SA_SHIRQ|SA_INTERRUPT, "aacraid", (void *)dev)<0) + { + printk(KERN_ERR "%s%d: Interrupt unavailable.\n", name, instance); + return -1; + } + /* + * Fill in the function dispatch table. + */ + dev->a_ops.adapter_interrupt = aac_rkt_interrupt_adapter; + dev->a_ops.adapter_enable_int = aac_rkt_enable_interrupt; + dev->a_ops.adapter_disable_int = aac_rkt_disable_interrupt; + dev->a_ops.adapter_notify = aac_rkt_notify_adapter; + dev->a_ops.adapter_sync_cmd = rkt_sync_cmd; + + if (aac_init_adapter(dev) == NULL) + return -1; + /* + * Start any kernel threads needed + */ + dev->thread_pid = kernel_thread((int (*)(void *))aac_command_thread, dev, 0); + if(dev->thread_pid < 0) + { + printk(KERN_ERR "aacraid: Unable to create rkt thread.\n"); + return -1; + } + /* + * Tell the adapter that all is configured, and it can start + * accepting requests + */ + aac_rkt_start_adapter(dev); + return 0; +} diff -Nru a/drivers/scsi/aacraid/rkt.c.unused b/drivers/scsi/aacraid/rkt.c.unused --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/scsi/aacraid/rkt.c.unused Thu Feb 19 23:16:29 2004 @@ -0,0 +1,416 @@ +/* + * Adaptec AAC series RAID controller driver + * (c) Copyright 2001 Red Hat Inc. + * + * based on the old aacraid driver that is.. + * Adaptec aacraid device driver for Linux. + * + * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Module Name: + * rkt.c + * + * Abstract: Hardware miniport for Drawbridge specific hardware functions. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "aacraid.h" + +static irqreturn_t aac_rkt_intr(int irq, void *dev_id, struct pt_regs *regs) +{ + struct aac_dev *dev = dev_id; + unsigned long bellbits; + u8 intstat, mask; + intstat = rkt_readb(dev, MUnit.OISR); + /* + * Read mask and invert because drawbridge is reversed. + * This allows us to only service interrupts that have + * been enabled. + */ + mask = ~(dev->OIMR); + /* Check to see if this is our interrupt. If it isn't just return */ + if (intstat & mask) + { + bellbits = rkt_readl(dev, OutboundDoorbellReg); + if (bellbits & DoorBellPrintfReady) { + aac_printf(dev, le32_to_cpu(rkt_readl (dev, IndexRegs.Mailbox[5]))); + rkt_writel(dev, MUnit.ODR,DoorBellPrintfReady); + rkt_writel(dev, InboundDoorbellReg,DoorBellPrintfDone); + } + else if (bellbits & DoorBellAdapterNormCmdReady) { + aac_command_normal(&dev->queues->queue[HostNormCmdQueue]); + rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdReady); + } + else if (bellbits & DoorBellAdapterNormRespReady) { + aac_response_normal(&dev->queues->queue[HostNormRespQueue]); + rkt_writel(dev, MUnit.ODR,DoorBellAdapterNormRespReady); + } + else if (bellbits & DoorBellAdapterNormCmdNotFull) { + rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull); + } + else if (bellbits & DoorBellAdapterNormRespNotFull) { + rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormCmdNotFull); + rkt_writel(dev, MUnit.ODR, DoorBellAdapterNormRespNotFull); + } + return IRQ_HANDLED; + } + return IRQ_NONE; +} + +/** + * aac_rkt_enable_interrupt - Enable event reporting + * @dev: Adapter + * @event: Event to enable + * + * Enable event reporting from the i960 for a given event. + */ + +static void aac_rkt_enable_interrupt(struct aac_dev * dev, u32 event) +{ + switch (event) { + + case HostNormCmdQue: + dev->irq_mask &= ~(OUTBOUNDDOORBELL_1); + break; + + case HostNormRespQue: + dev->irq_mask &= ~(OUTBOUNDDOORBELL_2); + break; + + case AdapNormCmdNotFull: + dev->irq_mask &= ~(OUTBOUNDDOORBELL_3); + break; + + case AdapNormRespNotFull: + dev->irq_mask &= ~(OUTBOUNDDOORBELL_4); + break; + } +} + +/** + * aac_rkt_disable_interrupt - Disable event reporting + * @dev: Adapter + * @event: Event to enable + * + * Disable event reporting from the i960 for a given event. + */ + +static void aac_rkt_disable_interrupt(struct aac_dev *dev, u32 event) +{ + switch (event) { + + case HostNormCmdQue: + dev->irq_mask |= (OUTBOUNDDOORBELL_1); + break; + + case HostNormRespQue: + dev->irq_mask |= (OUTBOUNDDOORBELL_2); + break; + + case AdapNormCmdNotFull: + dev->irq_mask |= (OUTBOUNDDOORBELL_3); + break; + + case AdapNormRespNotFull: + dev->irq_mask |= (OUTBOUNDDOORBELL_4); + break; + } +} + +/** + * rkt_sync_cmd - send a command and wait + * @dev: Adapter + * @command: Command to execute + * @p1: first parameter + * @ret: adapter status + * + * This routine will send a synchronous comamnd to the adapter and wait + * for its completion. + */ + +static int rkt_sync_cmd(struct aac_dev *dev, u32 command, u32 p1, u32 *status) +{ + unsigned long start; + int ok; + /* + * Write the command into Mailbox 0 + */ + rkt_writel(dev, InboundMailbox0, cpu_to_le32(command)); + /* + * Write the parameters into Mailboxes 1 - 4 + */ + rkt_writel(dev, InboundMailbox1, cpu_to_le32(p1)); + rkt_writel(dev, InboundMailbox2, 0); + rkt_writel(dev, InboundMailbox3, 0); + rkt_writel(dev, InboundMailbox4, 0); + /* + * Clear the synch command doorbell to start on a clean slate. + */ + rkt_writel(dev, OutboundDoorbellReg, OUTBOUNDDOORBELL_0); + /* + * Disable doorbell interrupts + */ + rkt_writeb(dev, MUnit.OIMR, dev->OIMR |= 0x04); + /* + * Force the completion of the mask register write before issuing + * the interrupt. + */ + rkt_readb (dev, MUnit.OIMR); + /* + * Signal that there is a new synch command + */ + rkt_writel(dev, InboundDoorbellReg, INBOUNDDOORBELL_0); + + ok = 0; + start = jiffies; + + /* + * Wait up to 30 seconds + */ + while (time_before(jiffies, start+30*HZ)) + { + udelay(5); /* Delay 5 microseconds to let Mon960 get info. */ + /* + * Mon960 will set doorbell0 bit when it has completed the command. + */ + if (rkt_readl(dev, OutboundDoorbellReg) & OUTBOUNDDOORBELL_0) { + /* + * Clear the doorbell. + */ + rkt_writel(dev, OutboundDoorbellReg, OUTBOUNDDOORBELL_0); + ok = 1; + break; + } + /* + * Yield the processor in case we are slow + */ + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(1); + } + if (ok != 1) { + /* + * Restore interrupt mask even though we timed out + */ + rkt_writeb(dev, MUnit.OIMR, dev->OIMR &= 0xfb); + return -ETIMEDOUT; + } + /* + * Pull the synch status from Mailbox 0. + */ + *status = le32_to_cpu(rkt_readl(dev, IndexRegs.Mailbox[0])); + /* + * Clear the synch command doorbell. + */ + rkt_writel(dev, OutboundDoorbellReg, OUTBOUNDDOORBELL_0); + /* + * Restore interrupt mask + */ + rkt_writeb(dev, MUnit.OIMR, dev->OIMR &= 0xfb); + return 0; + +} + +/** + * aac_rkt_interrupt_adapter - interrupt adapter + * @dev: Adapter + * + * Send an interrupt to the i960 and breakpoint it. + */ + +static void aac_rkt_interrupt_adapter(struct aac_dev *dev) +{ + u32 ret; + rkt_sync_cmd(dev, BREAKPOINT_REQUEST, 0, &ret); +} + +/** + * aac_rkt_notify_adapter - send an event to the adapter + * @dev: Adapter + * @event: Event to send + * + * Notify the i960 that something it probably cares about has + * happened. + */ + +static void aac_rkt_notify_adapter(struct aac_dev *dev, u32 event) +{ + switch (event) { + + case AdapNormCmdQue: + rkt_writel(dev, MUnit.IDR,INBOUNDDOORBELL_1); + break; + case HostNormRespNotFull: + rkt_writel(dev, MUnit.IDR,INBOUNDDOORBELL_4); + break; + case AdapNormRespQue: + rkt_writel(dev, MUnit.IDR,INBOUNDDOORBELL_2); + break; + case HostNormCmdNotFull: + rkt_writel(dev, MUnit.IDR,INBOUNDDOORBELL_3); + break; + case HostShutdown: +// rkt_sync_cmd(dev, HOST_CRASHING, 0, 0, 0, 0, &ret); + break; + case FastIo: + rkt_writel(dev, MUnit.IDR,INBOUNDDOORBELL_6); + break; + case AdapPrintfDone: + rkt_writel(dev, MUnit.IDR,INBOUNDDOORBELL_5); + break; + default: + BUG(); + break; + } +} + +/** + * aac_rkt_start_adapter - activate adapter + * @dev: Adapter + * + * Start up processing on an i960 based AAC adapter + */ + +static void aac_rkt_start_adapter(struct aac_dev *dev) +{ + u32 status; + struct aac_init *init; + + init = dev->init; + init->HostElapsedSeconds = cpu_to_le32(jiffies/HZ); + /* + * Tell the adapter we are back and up and running so it will scan + * its command queues and enable our interrupts + */ + dev->irq_mask = (DoorBellPrintfReady | OUTBOUNDDOORBELL_1 | OUTBOUNDDOORBELL_2 | OUTBOUNDDOORBELL_3 | OUTBOUNDDOORBELL_4); + /* + * First clear out all interrupts. Then enable the one's that we + * can handle. + */ + rkt_writeb(dev, MUnit.OIMR, 0xff); + rkt_writel(dev, MUnit.ODR, 0xffffffff); +// rkt_writeb(dev, MUnit.OIMR, ~(u8)OUTBOUND_DOORBELL_INTERRUPT_MASK); + rkt_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb); + + // We can only use a 32 bit address here + rkt_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, (u32)(ulong)dev->init_pa, &status); +} + +/** + * aac_rkt_init - initialize an i960 based AAC card + * @dev: device to configure + * @devnum: adapter number + * + * Allocate and set up resources for the i960 based AAC variants. The + * device_interface in the commregion will be allocated and linked + * to the comm region. + */ + +int aac_rkt_init(struct aac_dev *dev, unsigned long num) +{ + unsigned long start; + unsigned long status; + int instance; + const char * name; + + dev->devnum = num; + instance = dev->id; + name = dev->name; + + /* + * Map in the registers from the adapter. + */ + if((dev->regs.rkt = (struct rkt_registers *)ioremap((unsigned long)dev->scsi_host_ptr->base, 8192))==NULL) + { + printk(KERN_WARNING "aacraid: unable to map i960.\n" ); + return -1; + } + /* + * Check to see if the board failed any self tests. + */ + if (rkt_readl(dev, IndexRegs.Mailbox[7]) & SELF_TEST_FAILED) { + printk(KERN_ERR "%s%d: adapter self-test failed.\n", dev->name, instance); + return -1; + } + /* + * Check to see if the board panic'd while booting. + */ + if (rkt_readl(dev, IndexRegs.Mailbox[7]) & KERNEL_PANIC) { + printk(KERN_ERR "%s%d: adapter kernel panic'd.\n", dev->name, instance); + return -1; + } + start = jiffies; + /* + * Wait for the adapter to be up and running. Wait up to 3 minutes + */ + while (!(rkt_readl(dev, IndexRegs.Mailbox[7]) & KERNEL_UP_AND_RUNNING)) + { + if(time_after(jiffies, start+180*HZ)) + { + status = rkt_readl(dev, IndexRegs.Mailbox[7]) >> 16; + printk(KERN_ERR "%s%d: adapter kernel failed to start, init status = %ld.\n", dev->name, instance, status); + return -1; + } + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(1); + } + if (request_irq(dev->scsi_host_ptr->irq, aac_rkt_intr, SA_SHIRQ|SA_INTERRUPT, "aacraid", (void *)dev)<0) + { + printk(KERN_ERR "%s%d: Interrupt unavailable.\n", name, instance); + return -1; + } + /* + * Fill in the function dispatch table. + */ + dev->a_ops.adapter_interrupt = aac_rkt_interrupt_adapter; + dev->a_ops.adapter_enable_int = aac_rkt_enable_interrupt; + dev->a_ops.adapter_disable_int = aac_rkt_disable_interrupt; + dev->a_ops.adapter_notify = aac_rkt_notify_adapter; + dev->a_ops.adapter_sync_cmd = rkt_sync_cmd; + + if (aac_init_adapter(dev) == NULL) + return -1; + /* + * Start any kernel threads needed + */ + dev->thread_pid = kernel_thread((int (*)(void *))aac_command_thread, dev, 0); + if(dev->thread_pid < 0) + { + printk(KERN_ERR "aacraid: Unable to create rkt thread.\n"); + return -1; + } + /* + * Tell the adapter that all is configured, and it can start + * accepting requests + */ + aac_rkt_start_adapter(dev); + return 0; +} diff -Nru a/drivers/scsi/aacraid/rx.c b/drivers/scsi/aacraid/rx.c --- a/drivers/scsi/aacraid/rx.c Thu Feb 19 23:16:29 2004 +++ b/drivers/scsi/aacraid/rx.c Thu Feb 19 23:16:29 2004 @@ -56,7 +56,7 @@ * This allows us to only service interrupts that have * been enabled. */ - mask = ~(rx_readb(dev, MUnit.OIMR)); + mask = ~(dev->OIMR); /* Check to see if this is our interrupt. If it isn't just return */ if (intstat & mask) { @@ -179,7 +179,7 @@ /* * Disable doorbell interrupts */ - rx_writeb(dev, MUnit.OIMR, rx_readb(dev, MUnit.OIMR) | 0x04); + rx_writeb(dev, MUnit.OIMR, dev->OIMR |= 0x04); /* * Force the completion of the mask register write before issuing * the interrupt. @@ -220,7 +220,7 @@ /* * Restore interrupt mask even though we timed out */ - rx_writeb(dev, MUnit.OIMR, rx_readl(dev, MUnit.OIMR) & 0xfb); + rx_writeb(dev, MUnit.OIMR, dev->OIMR &= 0xfb); return -ETIMEDOUT; } /* @@ -234,7 +234,7 @@ /* * Restore interrupt mask */ - rx_writeb(dev, MUnit.OIMR, rx_readl(dev, MUnit.OIMR) & 0xfb); + rx_writeb(dev, MUnit.OIMR, dev->OIMR &= 0xfb); return 0; } @@ -318,7 +318,7 @@ rx_writeb(dev, MUnit.OIMR, 0xff); rx_writel(dev, MUnit.ODR, 0xffffffff); // rx_writeb(dev, MUnit.OIMR, ~(u8)OUTBOUND_DOORBELL_INTERRUPT_MASK); - rx_writeb(dev, MUnit.OIMR, 0xfb); + rx_writeb(dev, MUnit.OIMR, dev->OIMR = 0xfb); // We can only use a 32 bit address here rx_sync_cmd(dev, INIT_STRUCT_BASE_ADDRESS, (u32)(ulong)dev->init_pa, &status); diff -Nru a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c --- a/drivers/scsi/g_NCR5380.c Thu Feb 19 23:16:29 2004 +++ b/drivers/scsi/g_NCR5380.c Thu Feb 19 23:16:29 2004 @@ -450,7 +450,7 @@ instance->irq = NCR5380_probe_irq(instance, 0xffff); if (instance->irq != SCSI_IRQ_NONE) - if (request_irq(instance->irq, generic_NCR5380_intr, SA_INTERRUPT, "NCR5380", NULL)) { + if (request_irq(instance->irq, generic_NCR5380_intr, SA_INTERRUPT, "NCR5380", instance)) { printk(KERN_WARNING "scsi%d : IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq); instance->irq = SCSI_IRQ_NONE; } diff -Nru a/drivers/scsi/ini9100u.c b/drivers/scsi/ini9100u.c --- a/drivers/scsi/ini9100u.c Thu Feb 19 23:16:29 2004 +++ b/drivers/scsi/ini9100u.c Thu Feb 19 23:16:29 2004 @@ -272,6 +272,17 @@ return (pSRB); } +static irqreturn_t i91u_intr(int irqno, void *dev_id, struct pt_regs *regs) +{ + struct Scsi_Host *dev = dev_id; + unsigned long flags; + + spin_lock_irqsave(dev->host_lock, flags); + tul_isr((HCS *)hreg->base); + spin_unlock_irqrestore(dev->host_lock, flags); + return IRQ_HANDLED; +} + /* called from init/main.c */ void i91u_setup(char *str, int *ints) @@ -396,8 +407,7 @@ pHCB->HCS_Index = i; /* 7/29/98 */ hreg = scsi_register(tpnt, sizeof(HCS)); - if(hreg == NULL) - { + if(hreg == NULL) { release_region(pHCB->HCS_Base, 256); return 0; } @@ -413,48 +423,10 @@ hreg->sg_tablesize = TOTAL_SG_ENTRY; /* Maximun support is 32 */ /* Initial tulip chip */ - switch (i) { - case 0: - ok = request_irq(pHCB->HCS_Intr, i91u_intr0, SA_INTERRUPT | SA_SHIRQ, "i91u", hreg); - break; - case 1: - ok = request_irq(pHCB->HCS_Intr, i91u_intr1, SA_INTERRUPT | SA_SHIRQ, "i91u", hreg); - break; - case 2: - ok = request_irq(pHCB->HCS_Intr, i91u_intr2, SA_INTERRUPT | SA_SHIRQ, "i91u", hreg); - break; - case 3: - ok = request_irq(pHCB->HCS_Intr, i91u_intr3, SA_INTERRUPT | SA_SHIRQ, "i91u", hreg); - break; - case 4: - ok = request_irq(pHCB->HCS_Intr, i91u_intr4, SA_INTERRUPT | SA_SHIRQ, "i91u", hreg); - break; - case 5: - ok = request_irq(pHCB->HCS_Intr, i91u_intr5, SA_INTERRUPT | SA_SHIRQ, "i91u", hreg); - break; - case 6: - ok = request_irq(pHCB->HCS_Intr, i91u_intr6, SA_INTERRUPT | SA_SHIRQ, "i91u", hreg); - break; - case 7: - ok = request_irq(pHCB->HCS_Intr, i91u_intr7, SA_INTERRUPT | SA_SHIRQ, "i91u", hreg); - break; - default: - i91u_panic("i91u: Too many host adapters\n"); - break; - } + ok = request_irq(pHCB->HCS_Intr, i91u_intr, SA_INTERRUPT | SA_SHIRQ, "i91u", hreg); if (ok < 0) { - if (ok == -EINVAL) { - printk("i91u: bad IRQ %d.\n", pHCB->HCS_Intr); - printk(" Contact author.\n"); - } else if (ok == -EBUSY) - printk("i91u: IRQ %d already in use. Configure another.\n", - pHCB->HCS_Intr); - else { - printk("\ni91u: Unexpected error code on requesting IRQ %d.\n", - pHCB->HCS_Intr); - printk(" Contact author.\n"); - } - i91u_panic("i91u: driver needs an IRQ.\n"); + printk(KERN_WARNING "i91u: unable to request IRQ %d\n\n", pHCB->HCS_Intr); + return 0; } } @@ -729,137 +701,6 @@ tul_release_scb(pHCB, pSCB); /* Release SCB for current channel */ } return; -} - -/* - * Interrupts handler (main routine of the driver) - */ -static irqreturn_t i91u_intr0(int irqno, void *dev_id, struct pt_regs *regs) -{ - unsigned long flags; - struct Scsi_Host *dev = dev_id; - - if (tul_hcs[0].HCS_Intr != irqno) - return IRQ_NONE; - - spin_lock_irqsave(dev->host_lock, flags); - - tul_isr(&tul_hcs[0]); - - spin_unlock_irqrestore(dev->host_lock, flags); - return IRQ_HANDLED; -} - -static irqreturn_t i91u_intr1(int irqno, void *dev_id, struct pt_regs *regs) -{ - unsigned long flags; - struct Scsi_Host *dev = dev_id; - - if (tul_hcs[1].HCS_Intr != irqno) - return IRQ_NONE; - - spin_lock_irqsave(dev->host_lock, flags); - - tul_isr(&tul_hcs[1]); - - spin_unlock_irqrestore(dev->host_lock, flags); - return IRQ_HANDLED; -} - -static irqreturn_t i91u_intr2(int irqno, void *dev_id, struct pt_regs *regs) -{ - unsigned long flags; - struct Scsi_Host *dev = dev_id; - - if (tul_hcs[2].HCS_Intr != irqno) - return IRQ_NONE; - - spin_lock_irqsave(dev->host_lock, flags); - - tul_isr(&tul_hcs[2]); - - spin_unlock_irqrestore(dev->host_lock, flags); - return IRQ_HANDLED; -} - -static irqreturn_t i91u_intr3(int irqno, void *dev_id, struct pt_regs *regs) -{ - unsigned long flags; - struct Scsi_Host *dev = dev_id; - - if (tul_hcs[3].HCS_Intr != irqno) - return IRQ_NONE; - - spin_lock_irqsave(dev->host_lock, flags); - - tul_isr(&tul_hcs[3]); - - spin_unlock_irqrestore(dev->host_lock, flags); - return IRQ_HANDLED; -} - -static irqreturn_t i91u_intr4(int irqno, void *dev_id, struct pt_regs *regs) -{ - unsigned long flags; - struct Scsi_Host *dev = dev_id; - - if (tul_hcs[4].HCS_Intr != irqno) - return IRQ_NONE; - - spin_lock_irqsave(dev->host_lock, flags); - - tul_isr(&tul_hcs[4]); - - spin_unlock_irqrestore(dev->host_lock, flags); - return IRQ_HANDLED; -} - -static irqreturn_t i91u_intr5(int irqno, void *dev_id, struct pt_regs *regs) -{ - unsigned long flags; - struct Scsi_Host *dev = dev_id; - - if (tul_hcs[5].HCS_Intr != irqno) - return IRQ_NONE; - - spin_lock_irqsave(dev->host_lock, flags); - - tul_isr(&tul_hcs[5]); - - spin_unlock_irqrestore(dev->host_lock, flags); - return IRQ_HANDLED; -} - -static irqreturn_t i91u_intr6(int irqno, void *dev_id, struct pt_regs *regs) -{ - unsigned long flags; - struct Scsi_Host *dev = dev_id; - - if (tul_hcs[6].HCS_Intr != irqno) - return IRQ_NONE; - - spin_lock_irqsave(dev->host_lock, flags); - - tul_isr(&tul_hcs[6]); - - spin_unlock_irqrestore(dev->host_lock, flags); - return IRQ_HANDLED; -} - -static irqreturn_t i91u_intr7(int irqno, void *dev_id, struct pt_regs *regs) -{ - unsigned long flags; - struct Scsi_Host *dev = dev_id; - - if (tul_hcs[7].HCS_Intr != irqno) - return IRQ_NONE; - - spin_lock_irqsave(dev->host_lock, flags); - - tul_isr(&tul_hcs[7]); - - spin_unlock_irqrestore(dev->host_lock, flags); - return IRQ_HANDLED; } /* diff -Nru a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c --- a/drivers/scsi/qla1280.c Thu Feb 19 23:16:29 2004 +++ b/drivers/scsi/qla1280.c Thu Feb 19 23:16:29 2004 @@ -348,7 +348,6 @@ #include #if LINUX_VERSION_CODE >= 0x020545 -#include /* for flush_cache_all() */ #include #include #include @@ -2122,8 +2121,6 @@ for(i = 0; i < cnt; i++) ((uint16_t *)ha->request_ring)[i] = cpu_to_le16(risc_code_address[i]); - - flush_cache_all(); mb[0] = MBC_LOAD_RAM; mb[1] = risc_address; diff -Nru a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c --- a/drivers/scsi/qla2xxx/qla_init.c Thu Feb 19 23:16:29 2004 +++ b/drivers/scsi/qla2xxx/qla_init.c Thu Feb 19 23:16:29 2004 @@ -690,12 +690,6 @@ for (i = 0; i < cnt; i++) req_ring[i] = cpu_to_le16(risc_code[i]); - /* - * Flush written firmware to the ha->request_ring buffer - * before DMA. - */ - flush_cache_all(); - if (fw_iter->addressing == FW_INFO_ADDR_NORMAL) { rval = qla2x00_load_ram(ha, ha->request_dma, risc_address, cnt); diff -Nru a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c --- a/drivers/scsi/qla2xxx/qla_isr.c Thu Feb 19 23:16:29 2004 +++ b/drivers/scsi/qla2xxx/qla_isr.c Thu Feb 19 23:16:29 2004 @@ -828,6 +828,7 @@ uint8_t lscsi_status; uint32_t resid; uint8_t sense_sz = 0; + uint16_t rsp_info_len; /* Fast path completion. */ if (le16_to_cpu(pkt->comp_status) == CS_COMPLETE && @@ -915,6 +916,24 @@ qla2x00_extend_timeout(cp, EXTEND_CMD_TIMEOUT); add_to_retry_queue(ha, sp); + return; + } + } + + /* Check for any FCP transport errors. */ + if (scsi_status & SS_RESPONSE_INFO_LEN_VALID) { + rsp_info_len = le16_to_cpu(pkt->rsp_info_len); + if (rsp_info_len > 3 && pkt->rsp_info[3]) { + DEBUG2(printk("scsi(%ld:%d:%d:%d) FCP I/O protocol " + "failure (%x/%02x%02x%02x%02x%02x%02x%02x%02x)..." + "retrying command\n", ha->host_no, b, t, l, + rsp_info_len, pkt->rsp_info[0], pkt->rsp_info[1], + pkt->rsp_info[2], pkt->rsp_info[3], + pkt->rsp_info[4], pkt->rsp_info[5], + pkt->rsp_info[6], pkt->rsp_info[7])); + + cp->result = DID_BUS_BUSY << 16; + add_to_done_queue(ha, sp); return; } } diff -Nru a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c --- a/drivers/scsi/qla2xxx/qla_mbx.c Thu Feb 19 23:16:29 2004 +++ b/drivers/scsi/qla2xxx/qla_mbx.c Thu Feb 19 23:16:29 2004 @@ -1421,7 +1421,7 @@ mcp->in_mb = MBX_0; mcp->buf_size = PORT_DATABASE_SIZE; mcp->flags = MBX_DMA_IN; - mcp->tov = ha->login_timeout * 2; + mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2); rval = qla2x00_mailbox_command(ha, mcp); if (rval == QLA_SUCCESS) { @@ -1774,8 +1774,7 @@ mcp->in_mb = MBX_0|MBX_1; mcp->buf_size = buf_size; mcp->flags = MBX_DMA_OUT|MBX_DMA_IN; - /*mcp->tov = ha->retry_count * ha->login_timeout * 2;*/ - mcp->tov = ha->login_timeout * 2; + mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2); rval = qla2x00_mailbox_command(ha, mcp); if (rval != QLA_SUCCESS) { @@ -1836,8 +1835,7 @@ mcp->mb[3] = area << 8 | al_pa; mcp->in_mb = MBX_7|MBX_6|MBX_2|MBX_1|MBX_0; - /*mcp->tov = ha->retry_count * ha->login_timeout * 2;*/ - mcp->tov = ha->login_timeout * 2; + mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2); mcp->flags = 0; rval = qla2x00_mailbox_command(ha, mcp); @@ -1909,7 +1907,7 @@ mcp->mb[2] = opt; mcp->out_mb = MBX_2|MBX_1|MBX_0; mcp->in_mb = MBX_7|MBX_6|MBX_1|MBX_0; - mcp->tov = ha->login_timeout * 2; + mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2); mcp->flags = 0; rval = qla2x00_mailbox_command(ha, mcp); @@ -2412,7 +2410,7 @@ mcp->in_mb = MBX_1|MBX_0; mcp->buf_size = FCAL_MAP_SIZE; mcp->flags = MBX_DMA_IN; - mcp->tov = ha->login_timeout * 2; + mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2); rval = qla2x00_mailbox_command(ha, mcp); if (rval == QLA_SUCCESS) { diff -Nru a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c --- a/drivers/scsi/scsi.c Thu Feb 19 23:16:29 2004 +++ b/drivers/scsi/scsi.c Thu Feb 19 23:16:29 2004 @@ -784,7 +784,7 @@ */ memset(cmd->sense_buffer, 0, sizeof(cmd->sense_buffer)); - return scsi_dispatch_cmd(cmd); + return scsi_queue_insert(cmd, SCSI_MLQUEUE_EH_RETRY); } /* diff -Nru a/drivers/scsi/scsi.h b/drivers/scsi/scsi.h --- a/drivers/scsi/scsi.h Thu Feb 19 23:16:29 2004 +++ b/drivers/scsi/scsi.h Thu Feb 19 23:16:29 2004 @@ -34,51 +34,11 @@ #define FALSE 0 #endif -#define MAX_SCSI_DEVICE_CODE 14 -extern const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE]; - #ifdef DEBUG #define SCSI_TIMEOUT (5*HZ) #else #define SCSI_TIMEOUT (2*HZ) #endif - -/* - * Use these to separate status msg and our bytes - * - * These are set by: - * - * status byte = set from target device - * msg_byte = return status from host adapter itself. - * host_byte = set by low-level driver to indicate status. - * driver_byte = set by mid-level. - */ -#define status_byte(result) (((result) >> 1) & 0x1f) -#define msg_byte(result) (((result) >> 8) & 0xff) -#define host_byte(result) (((result) >> 16) & 0xff) -#define driver_byte(result) (((result) >> 24) & 0xff) -#define suggestion(result) (driver_byte(result) & SUGGEST_MASK) - -#define sense_class(sense) (((sense) >> 4) & 0x7) -#define sense_error(sense) ((sense) & 0xf) -#define sense_valid(sense) ((sense) & 0x80); - - -#define IDENTIFY_BASE 0x80 -#define IDENTIFY(can_disconnect, lun) (IDENTIFY_BASE |\ - ((can_disconnect) ? 0x40 : 0) |\ - ((lun) & 0x07)) - -/* - * SCSI command sets - */ - -#define SCSI_UNKNOWN 0 -#define SCSI_1 1 -#define SCSI_1_CCS 2 -#define SCSI_2 3 -#define SCSI_3 4 - struct Scsi_Host; struct scsi_cmnd; diff -Nru a/drivers/scsi/tmscsim.c b/drivers/scsi/tmscsim.c --- a/drivers/scsi/tmscsim.c Thu Feb 19 23:16:29 2004 +++ b/drivers/scsi/tmscsim.c Thu Feb 19 23:16:29 2004 @@ -518,7 +518,6 @@ } -#ifndef CONFIG_SCSI_DC390T_NOGENSUPP int __initdata tmscsim_def[] = {7, 0 /* 10MHz */, PARITY_CHK_ | SEND_START_ | EN_DISCONNECT_ | SYNC_NEGO_ | TAG_QUEUEING_, @@ -546,7 +545,6 @@ if (tmscsim[4] > 5) tmscsim[4] = 4; if (tmscsim[5] > 180) tmscsim[5] = 180; } -#endif /* Override defaults on cmdline: * tmscsim: AdaptID, MaxSpeed (Index), DevMode (Bitmapped), AdaptMode (Bitmapped) @@ -2105,10 +2103,6 @@ if (dc390_CheckEEpromCheckSum (PDEV, index)) { -#ifdef CONFIG_SCSI_DC390T_NOGENSUPP - printk (KERN_ERR "DC390_init: No EEPROM found!\n"); - return( -1 ); -#else int speed; dc390_adapname = "AM53C974"; printk (KERN_INFO "DC390_init: No EEPROM found! Trying default settings ...\n"); @@ -2120,7 +2114,6 @@ " DevMode=0x%02x, AdaptMode=0x%02x, TaggedCmnds=%i (%i), DelayReset=%is\n", tmscsim[0], tmscsim[1], speed/10, speed%10, (UCHAR)tmscsim[2], (UCHAR)tmscsim[3], tmscsim[4], 2 << (tmscsim[4]), tmscsim[5]); -#endif } else { diff -Nru a/include/scsi/scsi.h b/include/scsi/scsi.h --- a/include/scsi/scsi.h Thu Feb 19 23:16:29 2004 +++ b/include/scsi/scsi.h Thu Feb 19 23:16:29 2004 @@ -12,13 +12,20 @@ /* - * SCSI command lengths + * SCSI command lengths */ extern const unsigned char scsi_command_size[8]; #define COMMAND_SIZE(opcode) scsi_command_size[((opcode) >> 5) & 7] /* + * SCSI device types + */ + +#define MAX_SCSI_DEVICE_CODE 14 +extern const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE]; + +/* * SCSI opcodes */ @@ -310,6 +317,42 @@ #define SCSI_MLQUEUE_HOST_BUSY 0x1055 #define SCSI_MLQUEUE_DEVICE_BUSY 0x1056 #define SCSI_MLQUEUE_EH_RETRY 0x1057 + +/* + * Use these to separate status msg and our bytes + * + * These are set by: + * + * status byte = set from target device + * msg_byte = return status from host adapter itself. + * host_byte = set by low-level driver to indicate status. + * driver_byte = set by mid-level. + */ +#define status_byte(result) (((result) >> 1) & 0x1f) +#define msg_byte(result) (((result) >> 8) & 0xff) +#define host_byte(result) (((result) >> 16) & 0xff) +#define driver_byte(result) (((result) >> 24) & 0xff) +#define suggestion(result) (driver_byte(result) & SUGGEST_MASK) + +#define sense_class(sense) (((sense) >> 4) & 0x7) +#define sense_error(sense) ((sense) & 0xf) +#define sense_valid(sense) ((sense) & 0x80); + + +#define IDENTIFY_BASE 0x80 +#define IDENTIFY(can_disconnect, lun) (IDENTIFY_BASE |\ + ((can_disconnect) ? 0x40 : 0) |\ + ((lun) & 0x07)) + +/* + * SCSI command sets + */ + +#define SCSI_UNKNOWN 0 +#define SCSI_1 1 +#define SCSI_1_CCS 2 +#define SCSI_2 3 +#define SCSI_3 4 /*