Loading Documentation/scsi/g_NCR5380.txt +23 −23 Original line number Diff line number Diff line Loading @@ -6,17 +6,15 @@ NCR53c400 extensions (c) 1994,1995,1996 Kevin Lentin This file documents the NCR53c400 extensions by Kevin Lentin and some enhancements to the NCR5380 core. This driver supports both NCR5380 and NCR53c400 cards in port or memory mapped modes. Currently this driver can only support one of those mapping modes at a time but it does support both of these chips at the same time. The next release of this driver will support port & memory mapped cards at the same time. It should be able to handle multiple different cards in the same machine. This driver supports NCR5380 and NCR53c400 and compatible cards in port or memory mapped modes. The drivers/scsi/Makefile has an override in it for the most common NCR53c400 card, the Trantor T130B in its default configuration: Port: 0x350 IRQ : 5 Use of an interrupt is recommended, if supported by the board, as this will allow targets to disconnect and thereby improve SCSI bus utilization. If the irq parameter is 254 or is omitted entirely, the driver will probe for the correct IRQ line automatically. If the irq parameter is 0 or 255 then no IRQ will be used. The NCR53c400 does not support DMA but it does have Pseudo-DMA which is supported by the driver. Loading Loading @@ -47,22 +45,24 @@ These old-style parameters can support only one card: dtc_3181e=1 to set up for a Domex Technology Corp 3181E board hp_c2502=1 to set up for a Hewlett Packard C2502 board e.g. OLD: modprobe g_NCR5380 ncr_irq=5 ncr_addr=0x350 ncr_5380=1 NEW: modprobe g_NCR5380 irq=5 base=0x350 card=0 for a port mapped NCR5380 board or OLD: modprobe g_NCR5380 ncr_irq=255 ncr_addr=0xc8000 ncr_53c400=1 NEW: modprobe g_NCR5380 irq=255 base=0xc8000 card=1 for a memory mapped NCR53C400 board with interrupts disabled or E.g. Trantor T130B in its default configuration: modprobe g_NCR5380 irq=5 base=0x350 card=1 or alternatively, using the old syntax, modprobe g_NCR5380 ncr_irq=5 ncr_addr=0x350 ncr_53c400=1 NEW: modprobe g_NCR5380 irq=0,7 base=0x240,0x300 card=3,4 for two cards: DTC3181 (in non-PnP mode) at 0x240 with no IRQ and HP C2502 at 0x300 with IRQ 7 E.g. a port mapped NCR5380 board, driver to probe for IRQ: modprobe g_NCR5380 base=0x350 card=0 or alternatively, modprobe g_NCR5380 ncr_addr=0x350 ncr_5380=1 (255 should be specified for no or DMA interrupt, 254 to autoprobe for an IRQ line if overridden on the command line.) E.g. a memory mapped NCR53C400 board with no IRQ: modprobe g_NCR5380 irq=255 base=0xc8000 card=1 or alternatively, modprobe g_NCR5380 ncr_irq=255 ncr_addr=0xc8000 ncr_53c400=1 E.g. two cards, DTC3181 (in non-PnP mode) at 0x240 with no IRQ and HP C2502 at 0x300 with IRQ 7: modprobe g_NCR5380 irq=0,7 base=0x240,0x300 card=3,4 Kevin Lentin K.Lentin@cs.monash.edu.au drivers/scsi/NCR5380.c +1 −76 Original line number Diff line number Diff line Loading @@ -97,9 +97,6 @@ * and macros and include this file in your driver. * * These macros control options : * AUTOPROBE_IRQ - if defined, the NCR5380_probe_irq() function will be * defined. * * AUTOSENSE - if defined, REQUEST SENSE will be performed automatically * for commands that return with a CHECK CONDITION status. * Loading Loading @@ -127,9 +124,7 @@ * NCR5380_dma_residual - residual byte count * * The generic driver is initialized by calling NCR5380_init(instance), * after setting the appropriate host specific fields and ID. If the * driver wishes to autoprobe for an IRQ line, the NCR5380_probe_irq(instance, * possible) function may be used. * after setting the appropriate host specific fields and ID. */ #ifndef NCR5380_io_delay Loading Loading @@ -351,76 +346,6 @@ static void NCR5380_print_phase(struct Scsi_Host *instance) } #endif static int probe_irq; /** * probe_intr - helper for IRQ autoprobe * @irq: interrupt number * @dev_id: unused * @regs: unused * * Set a flag to indicate the IRQ in question was received. This is * used by the IRQ probe code. */ static irqreturn_t probe_intr(int irq, void *dev_id) { probe_irq = irq; return IRQ_HANDLED; } /** * NCR5380_probe_irq - find the IRQ of an NCR5380 * @instance: NCR5380 controller * @possible: bitmask of ISA IRQ lines * * Autoprobe for the IRQ line used by the NCR5380 by triggering an IRQ * and then looking to see what interrupt actually turned up. */ static int __maybe_unused NCR5380_probe_irq(struct Scsi_Host *instance, int possible) { struct NCR5380_hostdata *hostdata = shost_priv(instance); unsigned long timeout; int trying_irqs, i, mask; for (trying_irqs = 0, i = 1, mask = 2; i < 16; ++i, mask <<= 1) if ((mask & possible) && (request_irq(i, &probe_intr, 0, "NCR-probe", NULL) == 0)) trying_irqs |= mask; timeout = jiffies + msecs_to_jiffies(250); probe_irq = NO_IRQ; /* * A interrupt is triggered whenever BSY = false, SEL = true * and a bit set in the SELECT_ENABLE_REG is asserted on the * SCSI bus. * * Note that the bus is only driven when the phase control signals * (I/O, C/D, and MSG) match those in the TCR, so we must reset that * to zero. */ NCR5380_write(TARGET_COMMAND_REG, 0); NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask); NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA | ICR_ASSERT_SEL); while (probe_irq == NO_IRQ && time_before(jiffies, timeout)) schedule_timeout_uninterruptible(1); NCR5380_write(SELECT_ENABLE_REG, 0); NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); for (i = 1, mask = 2; i < 16; ++i, mask <<= 1) if (trying_irqs & mask) free_irq(i, NULL); return probe_irq; } /** * NCR58380_info - report driver and host information * @instance: relevant scsi host instance Loading drivers/scsi/NCR5380.h +0 −11 Original line number Diff line number Diff line Loading @@ -199,16 +199,6 @@ #define PHASE_SR_TO_TCR(phase) ((phase) >> 2) /* * These are "special" values for the irq and dma_channel fields of the * Scsi_Host structure */ #define DMA_NONE 255 #define IRQ_AUTO 254 #define DMA_AUTO 254 #define PORT_AUTO 0xffff /* autoprobe io port for 53c400a */ #ifndef NO_IRQ #define NO_IRQ 0 #endif Loading Loading @@ -290,7 +280,6 @@ static void NCR5380_print(struct Scsi_Host *instance); #define NCR5380_dprint_phase(flg, arg) do {} while (0) #endif static int NCR5380_probe_irq(struct Scsi_Host *instance, int possible); static int NCR5380_init(struct Scsi_Host *instance, int flags); static int NCR5380_maybe_reset_bus(struct Scsi_Host *); static void NCR5380_exit(struct Scsi_Host *instance); Loading drivers/scsi/aacraid/linit.c +0 −2 Original line number Diff line number Diff line Loading @@ -160,7 +160,6 @@ static const struct pci_device_id aac_pci_tbl[] = { { 0x9005, 0x028b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 62 }, /* Adaptec PMC Series 6 (Tupelo) */ { 0x9005, 0x028c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 63 }, /* Adaptec PMC Series 7 (Denali) */ { 0x9005, 0x028d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 64 }, /* Adaptec PMC Series 8 */ { 0x9005, 0x028f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 65 }, /* Adaptec PMC Series 9 */ { 0,} }; MODULE_DEVICE_TABLE(pci, aac_pci_tbl); Loading Loading @@ -239,7 +238,6 @@ static struct aac_driver_ident aac_drivers[] = { { aac_src_init, "aacraid", "ADAPTEC ", "RAID ", 2, AAC_QUIRK_SRC }, /* Adaptec PMC Series 6 (Tupelo) */ { aac_srcv_init, "aacraid", "ADAPTEC ", "RAID ", 2, AAC_QUIRK_SRC }, /* Adaptec PMC Series 7 (Denali) */ { aac_srcv_init, "aacraid", "ADAPTEC ", "RAID ", 2, AAC_QUIRK_SRC }, /* Adaptec PMC Series 8 */ { aac_srcv_init, "aacraid", "ADAPTEC ", "RAID ", 2, AAC_QUIRK_SRC } /* Adaptec PMC Series 9 */ }; /** Loading drivers/scsi/g_NCR5380.c +130 −23 Original line number Diff line number Diff line Loading @@ -37,7 +37,7 @@ #define MAX_CARDS 8 /* old-style parameters for compatibility */ static int ncr_irq; static int ncr_irq = -1; static int ncr_addr; static int ncr_5380; static int ncr_53c400; Loading @@ -52,9 +52,9 @@ module_param(ncr_53c400a, int, 0); module_param(dtc_3181e, int, 0); module_param(hp_c2502, int, 0); static int irq[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; static int irq[] = { -1, -1, -1, -1, -1, -1, -1, -1 }; module_param_array(irq, int, NULL, 0); MODULE_PARM_DESC(irq, "IRQ number(s)"); MODULE_PARM_DESC(irq, "IRQ number(s) (0=none, 254=auto [default])"); static int base[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; module_param_array(base, int, NULL, 0); Loading @@ -67,6 +67,56 @@ MODULE_PARM_DESC(card, "card type (0=NCR5380, 1=NCR53C400, 2=NCR53C400A, 3=DTC31 MODULE_ALIAS("g_NCR5380_mmio"); MODULE_LICENSE("GPL"); static void g_NCR5380_trigger_irq(struct Scsi_Host *instance) { struct NCR5380_hostdata *hostdata = shost_priv(instance); /* * An interrupt is triggered whenever BSY = false, SEL = true * and a bit set in the SELECT_ENABLE_REG is asserted on the * SCSI bus. * * Note that the bus is only driven when the phase control signals * (I/O, C/D, and MSG) match those in the TCR. */ NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(NCR5380_read(STATUS_REG) & PHASE_MASK)); NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask); NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA | ICR_ASSERT_SEL); msleep(1); NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); NCR5380_write(SELECT_ENABLE_REG, 0); NCR5380_write(TARGET_COMMAND_REG, 0); } /** * g_NCR5380_probe_irq - find the IRQ of a NCR5380 or equivalent * @instance: SCSI host instance * * Autoprobe for the IRQ line used by the card by triggering an IRQ * and then looking to see what interrupt actually turned up. */ static int g_NCR5380_probe_irq(struct Scsi_Host *instance) { struct NCR5380_hostdata *hostdata = shost_priv(instance); int irq_mask, irq; NCR5380_read(RESET_PARITY_INTERRUPT_REG); irq_mask = probe_irq_on(); g_NCR5380_trigger_irq(instance); irq = probe_irq_off(irq_mask); NCR5380_read(RESET_PARITY_INTERRUPT_REG); if (irq <= 0) return NO_IRQ; return irq; } /* * Configure I/O address of 53C400A or DTC436 by writing magic numbers * to ports 0x779 and 0x379. Loading @@ -81,14 +131,33 @@ static void magic_configure(int idx, u8 irq, u8 magic[]) outb(magic[3], 0x379); outb(magic[4], 0x379); /* allowed IRQs for HP C2502 */ if (irq != 2 && irq != 3 && irq != 4 && irq != 5 && irq != 7) irq = 0; if (irq == 9) irq = 2; if (idx >= 0 && idx <= 7) cfg = 0x80 | idx | (irq << 4); outb(cfg, 0x379); } static irqreturn_t legacy_empty_irq_handler(int irq, void *dev_id) { return IRQ_HANDLED; } static int legacy_find_free_irq(int *irq_table) { while (*irq_table != -1) { if (!request_irq(*irq_table, legacy_empty_irq_handler, IRQF_PROBE_SHARED, "Test IRQ", (void *)irq_table)) { free_irq(*irq_table, (void *) irq_table); return *irq_table; } irq_table++; } return -1; } static unsigned int ncr_53c400a_ports[] = { 0x280, 0x290, 0x300, 0x310, 0x330, 0x340, 0x348, 0x350, 0 }; Loading @@ -101,6 +170,9 @@ static u8 ncr_53c400a_magic[] = { /* 53C400A & DTC436 */ static u8 hp_c2502_magic[] = { /* HP C2502 */ 0x0f, 0x22, 0xf0, 0x20, 0x80 }; static int hp_c2502_irqs[] = { 9, 5, 7, 3, 4, -1 }; static int generic_NCR5380_init_one(struct scsi_host_template *tpnt, struct device *pdev, int base, int irq, int board) Loading Loading @@ -248,6 +320,13 @@ static int generic_NCR5380_init_one(struct scsi_host_template *tpnt, } } /* Check for vacant slot */ NCR5380_write(MODE_REG, 0); if (NCR5380_read(MODE_REG) != 0) { ret = -ENODEV; goto out_unregister; } ret = NCR5380_init(instance, flags | FLAG_LATE_DMA_SETUP); if (ret) goto out_unregister; Loading @@ -262,31 +341,59 @@ static int generic_NCR5380_init_one(struct scsi_host_template *tpnt, NCR5380_maybe_reset_bus(instance); if (irq != IRQ_AUTO) instance->irq = irq; else instance->irq = NCR5380_probe_irq(instance, 0xffff); /* Compatibility with documented NCR5380 kernel parameters */ if (instance->irq == 255) instance->irq = NO_IRQ; if (irq == 255 || irq == 0) irq = NO_IRQ; else if (irq == -1) irq = IRQ_AUTO; if (board == BOARD_HP_C2502) { int *irq_table = hp_c2502_irqs; int board_irq = -1; switch (irq) { case NO_IRQ: board_irq = 0; break; case IRQ_AUTO: board_irq = legacy_find_free_irq(irq_table); break; default: while (*irq_table != -1) if (*irq_table++ == irq) board_irq = irq; } if (board_irq <= 0) { board_irq = 0; irq = NO_IRQ; } magic_configure(port_idx, board_irq, magic); } if (irq == IRQ_AUTO) { instance->irq = g_NCR5380_probe_irq(instance); if (instance->irq == NO_IRQ) shost_printk(KERN_INFO, instance, "no irq detected\n"); } else { instance->irq = irq; if (instance->irq == NO_IRQ) shost_printk(KERN_INFO, instance, "no irq provided\n"); } if (instance->irq != NO_IRQ) { /* set IRQ for HP C2502 */ if (board == BOARD_HP_C2502) magic_configure(port_idx, instance->irq, magic); if (request_irq(instance->irq, generic_NCR5380_intr, 0, "NCR5380", instance)) { printk(KERN_WARNING "scsi%d : IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq); instance->irq = NO_IRQ; shost_printk(KERN_INFO, instance, "irq %d denied\n", instance->irq); } else { shost_printk(KERN_INFO, instance, "irq %d acquired\n", instance->irq); } } if (instance->irq == NO_IRQ) { printk(KERN_INFO "scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no); printk(KERN_INFO "scsi%d : please jumper the board for a free IRQ.\n", instance->host_no); } ret = scsi_add_host(instance, pdev); if (ret) goto out_free_irq; Loading Loading @@ -597,7 +704,7 @@ static int __init generic_NCR5380_init(void) int ret = 0; /* compatibility with old-style parameters */ if (irq[0] == 0 && base[0] == 0 && card[0] == -1) { if (irq[0] == -1 && base[0] == 0 && card[0] == -1) { irq[0] = ncr_irq; base[0] = ncr_addr; if (ncr_5380) Loading Loading
Documentation/scsi/g_NCR5380.txt +23 −23 Original line number Diff line number Diff line Loading @@ -6,17 +6,15 @@ NCR53c400 extensions (c) 1994,1995,1996 Kevin Lentin This file documents the NCR53c400 extensions by Kevin Lentin and some enhancements to the NCR5380 core. This driver supports both NCR5380 and NCR53c400 cards in port or memory mapped modes. Currently this driver can only support one of those mapping modes at a time but it does support both of these chips at the same time. The next release of this driver will support port & memory mapped cards at the same time. It should be able to handle multiple different cards in the same machine. This driver supports NCR5380 and NCR53c400 and compatible cards in port or memory mapped modes. The drivers/scsi/Makefile has an override in it for the most common NCR53c400 card, the Trantor T130B in its default configuration: Port: 0x350 IRQ : 5 Use of an interrupt is recommended, if supported by the board, as this will allow targets to disconnect and thereby improve SCSI bus utilization. If the irq parameter is 254 or is omitted entirely, the driver will probe for the correct IRQ line automatically. If the irq parameter is 0 or 255 then no IRQ will be used. The NCR53c400 does not support DMA but it does have Pseudo-DMA which is supported by the driver. Loading Loading @@ -47,22 +45,24 @@ These old-style parameters can support only one card: dtc_3181e=1 to set up for a Domex Technology Corp 3181E board hp_c2502=1 to set up for a Hewlett Packard C2502 board e.g. OLD: modprobe g_NCR5380 ncr_irq=5 ncr_addr=0x350 ncr_5380=1 NEW: modprobe g_NCR5380 irq=5 base=0x350 card=0 for a port mapped NCR5380 board or OLD: modprobe g_NCR5380 ncr_irq=255 ncr_addr=0xc8000 ncr_53c400=1 NEW: modprobe g_NCR5380 irq=255 base=0xc8000 card=1 for a memory mapped NCR53C400 board with interrupts disabled or E.g. Trantor T130B in its default configuration: modprobe g_NCR5380 irq=5 base=0x350 card=1 or alternatively, using the old syntax, modprobe g_NCR5380 ncr_irq=5 ncr_addr=0x350 ncr_53c400=1 NEW: modprobe g_NCR5380 irq=0,7 base=0x240,0x300 card=3,4 for two cards: DTC3181 (in non-PnP mode) at 0x240 with no IRQ and HP C2502 at 0x300 with IRQ 7 E.g. a port mapped NCR5380 board, driver to probe for IRQ: modprobe g_NCR5380 base=0x350 card=0 or alternatively, modprobe g_NCR5380 ncr_addr=0x350 ncr_5380=1 (255 should be specified for no or DMA interrupt, 254 to autoprobe for an IRQ line if overridden on the command line.) E.g. a memory mapped NCR53C400 board with no IRQ: modprobe g_NCR5380 irq=255 base=0xc8000 card=1 or alternatively, modprobe g_NCR5380 ncr_irq=255 ncr_addr=0xc8000 ncr_53c400=1 E.g. two cards, DTC3181 (in non-PnP mode) at 0x240 with no IRQ and HP C2502 at 0x300 with IRQ 7: modprobe g_NCR5380 irq=0,7 base=0x240,0x300 card=3,4 Kevin Lentin K.Lentin@cs.monash.edu.au
drivers/scsi/NCR5380.c +1 −76 Original line number Diff line number Diff line Loading @@ -97,9 +97,6 @@ * and macros and include this file in your driver. * * These macros control options : * AUTOPROBE_IRQ - if defined, the NCR5380_probe_irq() function will be * defined. * * AUTOSENSE - if defined, REQUEST SENSE will be performed automatically * for commands that return with a CHECK CONDITION status. * Loading Loading @@ -127,9 +124,7 @@ * NCR5380_dma_residual - residual byte count * * The generic driver is initialized by calling NCR5380_init(instance), * after setting the appropriate host specific fields and ID. If the * driver wishes to autoprobe for an IRQ line, the NCR5380_probe_irq(instance, * possible) function may be used. * after setting the appropriate host specific fields and ID. */ #ifndef NCR5380_io_delay Loading Loading @@ -351,76 +346,6 @@ static void NCR5380_print_phase(struct Scsi_Host *instance) } #endif static int probe_irq; /** * probe_intr - helper for IRQ autoprobe * @irq: interrupt number * @dev_id: unused * @regs: unused * * Set a flag to indicate the IRQ in question was received. This is * used by the IRQ probe code. */ static irqreturn_t probe_intr(int irq, void *dev_id) { probe_irq = irq; return IRQ_HANDLED; } /** * NCR5380_probe_irq - find the IRQ of an NCR5380 * @instance: NCR5380 controller * @possible: bitmask of ISA IRQ lines * * Autoprobe for the IRQ line used by the NCR5380 by triggering an IRQ * and then looking to see what interrupt actually turned up. */ static int __maybe_unused NCR5380_probe_irq(struct Scsi_Host *instance, int possible) { struct NCR5380_hostdata *hostdata = shost_priv(instance); unsigned long timeout; int trying_irqs, i, mask; for (trying_irqs = 0, i = 1, mask = 2; i < 16; ++i, mask <<= 1) if ((mask & possible) && (request_irq(i, &probe_intr, 0, "NCR-probe", NULL) == 0)) trying_irqs |= mask; timeout = jiffies + msecs_to_jiffies(250); probe_irq = NO_IRQ; /* * A interrupt is triggered whenever BSY = false, SEL = true * and a bit set in the SELECT_ENABLE_REG is asserted on the * SCSI bus. * * Note that the bus is only driven when the phase control signals * (I/O, C/D, and MSG) match those in the TCR, so we must reset that * to zero. */ NCR5380_write(TARGET_COMMAND_REG, 0); NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask); NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA | ICR_ASSERT_SEL); while (probe_irq == NO_IRQ && time_before(jiffies, timeout)) schedule_timeout_uninterruptible(1); NCR5380_write(SELECT_ENABLE_REG, 0); NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); for (i = 1, mask = 2; i < 16; ++i, mask <<= 1) if (trying_irqs & mask) free_irq(i, NULL); return probe_irq; } /** * NCR58380_info - report driver and host information * @instance: relevant scsi host instance Loading
drivers/scsi/NCR5380.h +0 −11 Original line number Diff line number Diff line Loading @@ -199,16 +199,6 @@ #define PHASE_SR_TO_TCR(phase) ((phase) >> 2) /* * These are "special" values for the irq and dma_channel fields of the * Scsi_Host structure */ #define DMA_NONE 255 #define IRQ_AUTO 254 #define DMA_AUTO 254 #define PORT_AUTO 0xffff /* autoprobe io port for 53c400a */ #ifndef NO_IRQ #define NO_IRQ 0 #endif Loading Loading @@ -290,7 +280,6 @@ static void NCR5380_print(struct Scsi_Host *instance); #define NCR5380_dprint_phase(flg, arg) do {} while (0) #endif static int NCR5380_probe_irq(struct Scsi_Host *instance, int possible); static int NCR5380_init(struct Scsi_Host *instance, int flags); static int NCR5380_maybe_reset_bus(struct Scsi_Host *); static void NCR5380_exit(struct Scsi_Host *instance); Loading
drivers/scsi/aacraid/linit.c +0 −2 Original line number Diff line number Diff line Loading @@ -160,7 +160,6 @@ static const struct pci_device_id aac_pci_tbl[] = { { 0x9005, 0x028b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 62 }, /* Adaptec PMC Series 6 (Tupelo) */ { 0x9005, 0x028c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 63 }, /* Adaptec PMC Series 7 (Denali) */ { 0x9005, 0x028d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 64 }, /* Adaptec PMC Series 8 */ { 0x9005, 0x028f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 65 }, /* Adaptec PMC Series 9 */ { 0,} }; MODULE_DEVICE_TABLE(pci, aac_pci_tbl); Loading Loading @@ -239,7 +238,6 @@ static struct aac_driver_ident aac_drivers[] = { { aac_src_init, "aacraid", "ADAPTEC ", "RAID ", 2, AAC_QUIRK_SRC }, /* Adaptec PMC Series 6 (Tupelo) */ { aac_srcv_init, "aacraid", "ADAPTEC ", "RAID ", 2, AAC_QUIRK_SRC }, /* Adaptec PMC Series 7 (Denali) */ { aac_srcv_init, "aacraid", "ADAPTEC ", "RAID ", 2, AAC_QUIRK_SRC }, /* Adaptec PMC Series 8 */ { aac_srcv_init, "aacraid", "ADAPTEC ", "RAID ", 2, AAC_QUIRK_SRC } /* Adaptec PMC Series 9 */ }; /** Loading
drivers/scsi/g_NCR5380.c +130 −23 Original line number Diff line number Diff line Loading @@ -37,7 +37,7 @@ #define MAX_CARDS 8 /* old-style parameters for compatibility */ static int ncr_irq; static int ncr_irq = -1; static int ncr_addr; static int ncr_5380; static int ncr_53c400; Loading @@ -52,9 +52,9 @@ module_param(ncr_53c400a, int, 0); module_param(dtc_3181e, int, 0); module_param(hp_c2502, int, 0); static int irq[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; static int irq[] = { -1, -1, -1, -1, -1, -1, -1, -1 }; module_param_array(irq, int, NULL, 0); MODULE_PARM_DESC(irq, "IRQ number(s)"); MODULE_PARM_DESC(irq, "IRQ number(s) (0=none, 254=auto [default])"); static int base[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; module_param_array(base, int, NULL, 0); Loading @@ -67,6 +67,56 @@ MODULE_PARM_DESC(card, "card type (0=NCR5380, 1=NCR53C400, 2=NCR53C400A, 3=DTC31 MODULE_ALIAS("g_NCR5380_mmio"); MODULE_LICENSE("GPL"); static void g_NCR5380_trigger_irq(struct Scsi_Host *instance) { struct NCR5380_hostdata *hostdata = shost_priv(instance); /* * An interrupt is triggered whenever BSY = false, SEL = true * and a bit set in the SELECT_ENABLE_REG is asserted on the * SCSI bus. * * Note that the bus is only driven when the phase control signals * (I/O, C/D, and MSG) match those in the TCR. */ NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(NCR5380_read(STATUS_REG) & PHASE_MASK)); NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask); NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA | ICR_ASSERT_SEL); msleep(1); NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); NCR5380_write(SELECT_ENABLE_REG, 0); NCR5380_write(TARGET_COMMAND_REG, 0); } /** * g_NCR5380_probe_irq - find the IRQ of a NCR5380 or equivalent * @instance: SCSI host instance * * Autoprobe for the IRQ line used by the card by triggering an IRQ * and then looking to see what interrupt actually turned up. */ static int g_NCR5380_probe_irq(struct Scsi_Host *instance) { struct NCR5380_hostdata *hostdata = shost_priv(instance); int irq_mask, irq; NCR5380_read(RESET_PARITY_INTERRUPT_REG); irq_mask = probe_irq_on(); g_NCR5380_trigger_irq(instance); irq = probe_irq_off(irq_mask); NCR5380_read(RESET_PARITY_INTERRUPT_REG); if (irq <= 0) return NO_IRQ; return irq; } /* * Configure I/O address of 53C400A or DTC436 by writing magic numbers * to ports 0x779 and 0x379. Loading @@ -81,14 +131,33 @@ static void magic_configure(int idx, u8 irq, u8 magic[]) outb(magic[3], 0x379); outb(magic[4], 0x379); /* allowed IRQs for HP C2502 */ if (irq != 2 && irq != 3 && irq != 4 && irq != 5 && irq != 7) irq = 0; if (irq == 9) irq = 2; if (idx >= 0 && idx <= 7) cfg = 0x80 | idx | (irq << 4); outb(cfg, 0x379); } static irqreturn_t legacy_empty_irq_handler(int irq, void *dev_id) { return IRQ_HANDLED; } static int legacy_find_free_irq(int *irq_table) { while (*irq_table != -1) { if (!request_irq(*irq_table, legacy_empty_irq_handler, IRQF_PROBE_SHARED, "Test IRQ", (void *)irq_table)) { free_irq(*irq_table, (void *) irq_table); return *irq_table; } irq_table++; } return -1; } static unsigned int ncr_53c400a_ports[] = { 0x280, 0x290, 0x300, 0x310, 0x330, 0x340, 0x348, 0x350, 0 }; Loading @@ -101,6 +170,9 @@ static u8 ncr_53c400a_magic[] = { /* 53C400A & DTC436 */ static u8 hp_c2502_magic[] = { /* HP C2502 */ 0x0f, 0x22, 0xf0, 0x20, 0x80 }; static int hp_c2502_irqs[] = { 9, 5, 7, 3, 4, -1 }; static int generic_NCR5380_init_one(struct scsi_host_template *tpnt, struct device *pdev, int base, int irq, int board) Loading Loading @@ -248,6 +320,13 @@ static int generic_NCR5380_init_one(struct scsi_host_template *tpnt, } } /* Check for vacant slot */ NCR5380_write(MODE_REG, 0); if (NCR5380_read(MODE_REG) != 0) { ret = -ENODEV; goto out_unregister; } ret = NCR5380_init(instance, flags | FLAG_LATE_DMA_SETUP); if (ret) goto out_unregister; Loading @@ -262,31 +341,59 @@ static int generic_NCR5380_init_one(struct scsi_host_template *tpnt, NCR5380_maybe_reset_bus(instance); if (irq != IRQ_AUTO) instance->irq = irq; else instance->irq = NCR5380_probe_irq(instance, 0xffff); /* Compatibility with documented NCR5380 kernel parameters */ if (instance->irq == 255) instance->irq = NO_IRQ; if (irq == 255 || irq == 0) irq = NO_IRQ; else if (irq == -1) irq = IRQ_AUTO; if (board == BOARD_HP_C2502) { int *irq_table = hp_c2502_irqs; int board_irq = -1; switch (irq) { case NO_IRQ: board_irq = 0; break; case IRQ_AUTO: board_irq = legacy_find_free_irq(irq_table); break; default: while (*irq_table != -1) if (*irq_table++ == irq) board_irq = irq; } if (board_irq <= 0) { board_irq = 0; irq = NO_IRQ; } magic_configure(port_idx, board_irq, magic); } if (irq == IRQ_AUTO) { instance->irq = g_NCR5380_probe_irq(instance); if (instance->irq == NO_IRQ) shost_printk(KERN_INFO, instance, "no irq detected\n"); } else { instance->irq = irq; if (instance->irq == NO_IRQ) shost_printk(KERN_INFO, instance, "no irq provided\n"); } if (instance->irq != NO_IRQ) { /* set IRQ for HP C2502 */ if (board == BOARD_HP_C2502) magic_configure(port_idx, instance->irq, magic); if (request_irq(instance->irq, generic_NCR5380_intr, 0, "NCR5380", instance)) { printk(KERN_WARNING "scsi%d : IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq); instance->irq = NO_IRQ; shost_printk(KERN_INFO, instance, "irq %d denied\n", instance->irq); } else { shost_printk(KERN_INFO, instance, "irq %d acquired\n", instance->irq); } } if (instance->irq == NO_IRQ) { printk(KERN_INFO "scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no); printk(KERN_INFO "scsi%d : please jumper the board for a free IRQ.\n", instance->host_no); } ret = scsi_add_host(instance, pdev); if (ret) goto out_free_irq; Loading Loading @@ -597,7 +704,7 @@ static int __init generic_NCR5380_init(void) int ret = 0; /* compatibility with old-style parameters */ if (irq[0] == 0 && base[0] == 0 && card[0] == -1) { if (irq[0] == -1 && base[0] == 0 && card[0] == -1) { irq[0] = ncr_irq; base[0] = ncr_addr; if (ncr_5380) Loading