diff options
author | Tejun Heo <tj@kernel.org> | 2016-05-09 12:34:39 -0400 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2016-05-09 12:34:39 -0400 |
commit | 698f6700a6f19ba4550a722eaacf9f9d212b3fd9 (patch) | |
tree | ff63c9a23fe47870df8788ff5e7d9a552f6d4ed1 /drivers/scsi | |
parent | 7780081c1f04a4ea31331b5579ca010cc1f26c74 (diff) | |
parent | 13f307711b127d30fcf333a04365a217baf9ca2b (diff) |
Merge branch '4.7/scsi-queue' of git://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi into for-4.7-zac
Pulling in the dependencies for further ZAC changes.
Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'drivers/scsi')
95 files changed, 4084 insertions, 6269 deletions
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index e80768f8e579..98e5d51a3346 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -17,6 +17,7 @@ config SCSI tristate "SCSI device support" depends on BLOCK select SCSI_DMA if HAS_DMA + select SG_POOL ---help--- If you want to use a SCSI hard disk, SCSI tape drive, SCSI CD-ROM or any other SCSI device under Linux, say Y and make sure that you know @@ -202,12 +203,12 @@ config SCSI_ENCLOSURE certain enclosure conditions to be reported and is not required. config SCSI_CONSTANTS - bool "Verbose SCSI error reporting (kernel size +=75K)" + bool "Verbose SCSI error reporting (kernel size += 36K)" depends on SCSI help The error messages regarding your SCSI hardware will be easier to understand if you say Y here; it will enlarge your kernel by about - 75 KB. If in doubt, say Y. + 36 KB. If in doubt, say Y. config SCSI_LOGGING bool "SCSI logging facility" @@ -813,17 +814,6 @@ config SCSI_GENERIC_NCR5380_MMIO To compile this driver as a module, choose M here: the module will be called g_NCR5380_mmio. -config SCSI_GENERIC_NCR53C400 - bool "Enable NCR53c400 extensions" - depends on SCSI_GENERIC_NCR5380 - help - This enables certain optimizations for the NCR53c400 SCSI cards. - You might as well try it out. Note that this driver will only probe - for the Trantor T130B in its default configuration; you might have - to pass a command line option to the kernel at boot time if it does - not detect your card. See the file - <file:Documentation/scsi/g_NCR5380.txt> for details. - config SCSI_IPS tristate "IBM ServeRAID support" depends on PCI && SCSI diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c index 3eff2a69fe08..43908bbb3b23 100644 --- a/drivers/scsi/NCR5380.c +++ b/drivers/scsi/NCR5380.c @@ -29,29 +29,9 @@ * Ronald van Cuijlenborg, Alan Cox and others. */ -/* - * Further development / testing that should be done : - * 1. Cleanup the NCR5380_transfer_dma function and DMA operation complete - * code so that everything does the same thing that's done at the - * end of a pseudo-DMA read operation. - * - * 2. Fix REAL_DMA (interrupt driven, polled works fine) - - * basically, transfer size needs to be reduced by one - * and the last byte read as is done with PSEUDO_DMA. - * - * 4. Test SCSI-II tagged queueing (I have no devices which support - * tagged queueing) - */ +/* Ported to Atari by Roman Hodek and others. */ -#ifndef notyet -#undef REAL_DMA -#endif - -#ifdef BOARD_REQUIRES_NO_DELAY -#define io_recovery_delay(x) -#else -#define io_recovery_delay(x) udelay(x) -#endif +/* Adapted for the Sun 3 by Sam Creasey. */ /* * Design @@ -126,17 +106,10 @@ * DIFFERENTIAL - if defined, NCR53c81 chips will use external differential * transceivers. * - * DONT_USE_INTR - if defined, never use interrupts, even if we probe or - * override-configure an IRQ. - * * PSEUDO_DMA - if defined, PSEUDO DMA is used during the data transfer phases. * * REAL_DMA - if defined, REAL DMA is used during the data transfer phases. * - * REAL_DMA_POLL - if defined, REAL DMA is used but the driver doesn't - * rely on phase mismatch and EOP interrupts to determine end - * of phase. - * * These macros MUST be defined : * * NCR5380_read(register) - read from the specified register @@ -147,29 +120,29 @@ * specific implementation of the NCR5380 * * Either real DMA *or* pseudo DMA may be implemented - * REAL functions : - * NCR5380_REAL_DMA should be defined if real DMA is to be used. - * Note that the DMA setup functions should return the number of bytes - * that they were able to program the controller for. - * - * Also note that generic i386/PC versions of these macros are - * available as NCR5380_i386_dma_write_setup, - * NCR5380_i386_dma_read_setup, and NCR5380_i386_dma_residual. * * NCR5380_dma_write_setup(instance, src, count) - initialize * NCR5380_dma_read_setup(instance, dst, count) - initialize * NCR5380_dma_residual(instance); - residual count * - * PSEUDO functions : - * NCR5380_pwrite(instance, src, count) - * NCR5380_pread(instance, dst, 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. */ +#ifndef NCR5380_io_delay +#define NCR5380_io_delay(x) +#endif + +#ifndef NCR5380_acquire_dma_irq +#define NCR5380_acquire_dma_irq(x) (1) +#endif + +#ifndef NCR5380_release_dma_irq +#define NCR5380_release_dma_irq(x) +#endif + static int do_abort(struct Scsi_Host *); static void do_reset(struct Scsi_Host *); @@ -280,12 +253,20 @@ static struct { {0, NULL} }, basrs[] = { + {BASR_END_DMA_TRANSFER, "END OF DMA"}, + {BASR_DRQ, "DRQ"}, + {BASR_PARITY_ERROR, "PARITY ERROR"}, + {BASR_IRQ, "IRQ"}, + {BASR_PHASE_MATCH, "PHASE MATCH"}, + {BASR_BUSY_ERROR, "BUSY ERROR"}, {BASR_ATN, "ATN"}, {BASR_ACK, "ACK"}, {0, NULL} }, icrs[] = { {ICR_ASSERT_RST, "ASSERT RST"}, + {ICR_ARBITRATION_PROGRESS, "ARB. IN PROGRESS"}, + {ICR_ARBITRATION_LOST, "LOST ARB."}, {ICR_ASSERT_ACK, "ASSERT ACK"}, {ICR_ASSERT_BSY, "ASSERT BSY"}, {ICR_ASSERT_SEL, "ASSERT SEL"}, @@ -294,14 +275,14 @@ icrs[] = { {0, NULL} }, mrs[] = { - {MR_BLOCK_DMA_MODE, "MODE BLOCK DMA"}, - {MR_TARGET, "MODE TARGET"}, - {MR_ENABLE_PAR_CHECK, "MODE PARITY CHECK"}, - {MR_ENABLE_PAR_INTR, "MODE PARITY INTR"}, - {MR_ENABLE_EOP_INTR, "MODE EOP INTR"}, - {MR_MONITOR_BSY, "MODE MONITOR BSY"}, - {MR_DMA_MODE, "MODE DMA"}, - {MR_ARBITRATE, "MODE ARBITRATION"}, + {MR_BLOCK_DMA_MODE, "BLOCK DMA MODE"}, + {MR_TARGET, "TARGET"}, + {MR_ENABLE_PAR_CHECK, "PARITY CHECK"}, + {MR_ENABLE_PAR_INTR, "PARITY INTR"}, + {MR_ENABLE_EOP_INTR, "EOP INTR"}, + {MR_MONITOR_BSY, "MONITOR BSY"}, + {MR_DMA_MODE, "DMA MODE"}, + {MR_ARBITRATE, "ARBITRATE"}, {0, NULL} }; @@ -322,23 +303,23 @@ static void NCR5380_print(struct Scsi_Host *instance) icr = NCR5380_read(INITIATOR_COMMAND_REG); basr = NCR5380_read(BUS_AND_STATUS_REG); - printk("STATUS_REG: %02x ", status); + printk(KERN_DEBUG "SR = 0x%02x : ", status); for (i = 0; signals[i].mask; ++i) if (status & signals[i].mask) - printk(",%s", signals[i].name); - printk("\nBASR: %02x ", basr); + printk(KERN_CONT "%s, ", signals[i].name); + printk(KERN_CONT "\nBASR = 0x%02x : ", basr); for (i = 0; basrs[i].mask; ++i) if (basr & basrs[i].mask) - printk(",%s", basrs[i].name); - printk("\nICR: %02x ", icr); + printk(KERN_CONT "%s, ", basrs[i].name); + printk(KERN_CONT "\nICR = 0x%02x : ", icr); for (i = 0; icrs[i].mask; ++i) if (icr & icrs[i].mask) - printk(",%s", icrs[i].name); - printk("\nMODE: %02x ", mr); + printk(KERN_CONT "%s, ", icrs[i].name); + printk(KERN_CONT "\nMR = 0x%02x : ", mr); for (i = 0; mrs[i].mask; ++i) if (mr & mrs[i].mask) - printk(",%s", mrs[i].name); - printk("\n"); + printk(KERN_CONT "%s, ", mrs[i].name); + printk(KERN_CONT "\n"); } static struct { @@ -477,52 +458,18 @@ static void prepare_info(struct Scsi_Host *instance) instance->base, instance->irq, instance->can_queue, instance->cmd_per_lun, instance->sg_tablesize, instance->this_id, - hostdata->flags & FLAG_NO_DMA_FIXUP ? "NO_DMA_FIXUP " : "", + hostdata->flags & FLAG_DMA_FIXUP ? "DMA_FIXUP " : "", hostdata->flags & FLAG_NO_PSEUDO_DMA ? "NO_PSEUDO_DMA " : "", hostdata->flags & FLAG_TOSHIBA_DELAY ? "TOSHIBA_DELAY " : "", -#ifdef AUTOPROBE_IRQ - "AUTOPROBE_IRQ " -#endif #ifdef DIFFERENTIAL "DIFFERENTIAL " #endif -#ifdef REAL_DMA - "REAL_DMA " -#endif -#ifdef REAL_DMA_POLL - "REAL_DMA_POLL " -#endif #ifdef PARITY "PARITY " #endif -#ifdef PSEUDO_DMA - "PSEUDO_DMA " -#endif ""); } -#ifdef PSEUDO_DMA -static int __maybe_unused NCR5380_write_info(struct Scsi_Host *instance, - char *buffer, int length) -{ - struct NCR5380_hostdata *hostdata = shost_priv(instance); - - hostdata->spin_max_r = 0; - hostdata->spin_max_w = 0; - return 0; -} - -static int __maybe_unused NCR5380_show_info(struct seq_file *m, - struct Scsi_Host *instance) -{ - struct NCR5380_hostdata *hostdata = shost_priv(instance); - - seq_printf(m, "Highwater I/O busy spin counts: write %d, read %d\n", - hostdata->spin_max_w, hostdata->spin_max_r); - return 0; -} -#endif - /** * NCR5380_init - initialise an NCR5380 * @instance: adapter to configure @@ -543,6 +490,8 @@ static int NCR5380_init(struct Scsi_Host *instance, int flags) int i; unsigned long deadline; + instance->max_lun = 7; + hostdata->host = instance; hostdata->id_mask = 1 << instance->this_id; hostdata->id_higher_mask = 0; @@ -551,9 +500,8 @@ static int NCR5380_init(struct Scsi_Host *instance, int flags) hostdata->id_higher_mask |= i; for (i = 0; i < 8; ++i) hostdata->busy[i] = 0; -#ifdef REAL_DMA - hostdata->dmalen = 0; -#endif + hostdata->dma_len = 0; + spin_lock_init(&hostdata->lock); hostdata->connected = NULL; hostdata->sensing = NULL; @@ -719,6 +667,9 @@ static int NCR5380_queue_command(struct Scsi_Host *instance, cmd->result = 0; + if (!NCR5380_acquire_dma_irq(instance)) + return SCSI_MLQUEUE_HOST_BUSY; + spin_lock_irqsave(&hostdata->lock, flags); /* @@ -743,6 +694,19 @@ static int NCR5380_queue_command(struct Scsi_Host *instance, return 0; } +static inline void maybe_release_dma_irq(struct Scsi_Host *instance) +{ + struct NCR5380_hostdata *hostdata = shost_priv(instance); + + /* Caller does the locking needed to set & test these data atomically */ + if (list_empty(&hostdata->disconnected) && + list_empty(&hostdata->unissued) && + list_empty(&hostdata->autosense) && + !hostdata->connected && + !hostdata->selecting) + NCR5380_release_dma_irq(instance); +} + /** * dequeue_next_cmd - dequeue a command for processing * @instance: the scsi host instance @@ -844,17 +808,14 @@ static void NCR5380_main(struct work_struct *work) if (!NCR5380_select(instance, cmd)) { dsprintk(NDEBUG_MAIN, instance, "main: select complete\n"); + maybe_release_dma_irq(instance); } else { dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES, instance, "main: select failed, returning %p to queue\n", cmd); requeue_cmd(instance, cmd); } } - if (hostdata->connected -#ifdef REAL_DMA - && !hostdata->dmalen -#endif - ) { + if (hostdata->connected && !hostdata->dma_len) { dsprintk(NDEBUG_MAIN, instance, "main: performing information transfer\n"); NCR5380_information_transfer(instance); done = 0; @@ -865,7 +826,88 @@ static void NCR5380_main(struct work_struct *work) } while (!done); } -#ifndef DONT_USE_INTR +/* + * NCR5380_dma_complete - finish DMA transfer + * @instance: the scsi host instance + * + * Called by the interrupt handler when DMA finishes or a phase + * mismatch occurs (which would end the DMA transfer). + */ + +static void NCR5380_dma_complete(struct Scsi_Host *instance) +{ + struct NCR5380_hostdata *hostdata = shost_priv(instance); + int transferred; + unsigned char **data; + int *count; + int saved_data = 0, overrun = 0; |