summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFinn Thain <fthain@telegraphics.com.au>2018-09-26 21:17:11 -0400
committerMartin K. Petersen <martin.petersen@oracle.com>2018-09-28 02:22:43 -0400
commit6b0e87a6aafe12d75c2bea6fc8e49e88b98b3083 (patch)
tree934fe85d3e574564027372ddb5bfdebff4c8fb14
parentca694afad707cb3ae2fdef3b28454444d9ac726e (diff)
scsi: NCR5380: Check for bus reset
The SR_RST bit isn't latched. Hence, detecting a bus reset isn't reliable. When it is detected, the right thing to do is to drop all connected and disconnected commands. The code for that is already present so refactor it and call it when SR_RST is set. Tested-by: Michael Schmitz <schmitzmic@gmail.com> Signed-off-by: Finn Thain <fthain@telegraphics.com.au> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r--drivers/scsi/NCR5380.c74
1 files changed, 45 insertions, 29 deletions
diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
index b9a3eb0647e4..8429c855701f 100644
--- a/drivers/scsi/NCR5380.c
+++ b/drivers/scsi/NCR5380.c
@@ -131,6 +131,7 @@
131 131
132static int do_abort(struct Scsi_Host *); 132static int do_abort(struct Scsi_Host *);
133static void do_reset(struct Scsi_Host *); 133static void do_reset(struct Scsi_Host *);
134static void bus_reset_cleanup(struct Scsi_Host *);
134 135
135/** 136/**
136 * initialize_SCp - init the scsi pointer field 137 * initialize_SCp - init the scsi pointer field
@@ -883,7 +884,14 @@ static irqreturn_t __maybe_unused NCR5380_intr(int irq, void *dev_id)
883 /* Probably Bus Reset */ 884 /* Probably Bus Reset */
884 NCR5380_read(RESET_PARITY_INTERRUPT_REG); 885 NCR5380_read(RESET_PARITY_INTERRUPT_REG);
885 886
886 dsprintk(NDEBUG_INTR, instance, "unknown interrupt\n"); 887 if (sr & SR_RST) {
888 /* Certainly Bus Reset */
889 shost_printk(KERN_WARNING, instance,
890 "bus reset interrupt\n");
891 bus_reset_cleanup(instance);
892 } else {
893 dsprintk(NDEBUG_INTR, instance, "unknown interrupt\n");
894 }
887#ifdef SUN3_SCSI_VME 895#ifdef SUN3_SCSI_VME
888 dregs->csr |= CSR_DMA_ENABLE; 896 dregs->csr |= CSR_DMA_ENABLE;
889#endif 897#endif
@@ -2305,31 +2313,12 @@ out:
2305} 2313}
2306 2314
2307 2315
2308/** 2316static void bus_reset_cleanup(struct Scsi_Host *instance)
2309 * NCR5380_host_reset - reset the SCSI host
2310 * @cmd: SCSI command undergoing EH
2311 *
2312 * Returns SUCCESS
2313 */
2314
2315static int NCR5380_host_reset(struct scsi_cmnd *cmd)
2316{ 2317{
2317 struct Scsi_Host *instance = cmd->device->host;
2318 struct NCR5380_hostdata *hostdata = shost_priv(instance); 2318 struct NCR5380_hostdata *hostdata = shost_priv(instance);
2319 int i; 2319 int i;
2320 unsigned long flags;
2321 struct NCR5380_cmd *ncmd; 2320 struct NCR5380_cmd *ncmd;
2322 2321
2323 spin_lock_irqsave(&hostdata->lock, flags);
2324
2325#if (NDEBUG & NDEBUG_ANY)
2326 shost_printk(KERN_INFO, instance, __func__);
2327#endif
2328 NCR5380_dprint(NDEBUG_ANY, instance);
2329 NCR5380_dprint_phase(NDEBUG_ANY, instance);
2330
2331 do_reset(instance);
2332
2333 /* reset NCR registers */ 2322 /* reset NCR registers */
2334 NCR5380_write(MODE_REG, MR_BASE); 2323 NCR5380_write(MODE_REG, MR_BASE);
2335 NCR5380_write(TARGET_COMMAND_REG, 0); 2324 NCR5380_write(TARGET_COMMAND_REG, 0);
@@ -2341,14 +2330,6 @@ static int NCR5380_host_reset(struct scsi_cmnd *cmd)
2341 * commands! 2330 * commands!
2342 */ 2331 */
2343 2332
2344 list_for_each_entry(ncmd, &hostdata->unissued, list) {
2345 struct scsi_cmnd *cmd = NCR5380_to_scmd(ncmd);
2346
2347 cmd->result = DID_RESET << 16;
2348 cmd->scsi_done(cmd);
2349 }
2350 INIT_LIST_HEAD(&hostdata->unissued);
2351
2352 if (hostdata->selecting) { 2333 if (hostdata->selecting) {
2353 hostdata->selecting->result = DID_RESET << 16; 2334 hostdata->selecting->result = DID_RESET << 16;
2354 complete_cmd(instance, hostdata->selecting); 2335 complete_cmd(instance, hostdata->selecting);
@@ -2382,6 +2363,41 @@ static int NCR5380_host_reset(struct scsi_cmnd *cmd)
2382 2363
2383 queue_work(hostdata->work_q, &hostdata->main_task); 2364 queue_work(hostdata->work_q, &hostdata->main_task);
2384 maybe_release_dma_irq(instance); 2365 maybe_release_dma_irq(instance);
2366}
2367
2368/**
2369 * NCR5380_host_reset - reset the SCSI host
2370 * @cmd: SCSI command undergoing EH
2371 *
2372 * Returns SUCCESS
2373 */
2374
2375static int NCR5380_host_reset(struct scsi_cmnd *cmd)
2376{
2377 struct Scsi_Host *instance = cmd->device->host;
2378 struct NCR5380_hostdata *hostdata = shost_priv(instance);
2379 unsigned long flags;
2380 struct NCR5380_cmd *ncmd;
2381
2382 spin_lock_irqsave(&hostdata->lock, flags);
2383
2384#if (NDEBUG & NDEBUG_ANY)
2385 shost_printk(KERN_INFO, instance, __func__);
2386#endif
2387 NCR5380_dprint(NDEBUG_ANY, instance);
2388 NCR5380_dprint_phase(NDEBUG_ANY, instance);
2389
2390 list_for_each_entry(ncmd, &hostdata->unissued, list) {
2391 struct scsi_cmnd *scmd = NCR5380_to_scmd(ncmd);
2392
2393 scmd->result = DID_RESET << 16;
2394 scmd->scsi_done(scmd);
2395 }
2396 INIT_LIST_HEAD(&hostdata->unissued);
2397
2398 do_reset(instance);
2399 bus_reset_cleanup(instance);
2400
2385 spin_unlock_irqrestore(&hostdata->lock, flags); 2401 spin_unlock_irqrestore(&hostdata->lock, flags);
2386 2402
2387 return SUCCESS; 2403 return SUCCESS;