Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1300181 > unrolled thread
| Started by | Finn Thain <fthain@telegraphics.com.au> |
|---|---|
| First post | 2016-01-03 06:20 +0100 |
| Last post | 2016-01-07 04:00 +0100 |
| Articles | 20 on this page of 84 — 4 participants |
Back to article view | Back to linux.kernel
[PATCH v4 00/78] More fixes, cleanup and modernization for NCR5380 drivers Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:20 +0100
[PATCH v4 63/78] atari_NCR5380: Remove HOSTNO macro from printk() and seq_printf() calls Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:30 +0100
[PATCH v4 29/78] ncr5380: Remove references to linked commands Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:30 +0100
[PATCH v4 73/78] ncr5380: Fix pseudo DMA transfers on 53C400 Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:30 +0100
[PATCH v4 21/78] ncr5380: Sleep when polling, if possible Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:30 +0100
[PATCH v4 33/78] atari_NCR5380: Set do_abort() timeouts Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:30 +0100
[PATCH v4 53/78] ncr5380: Use shost_priv helper Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:30 +0100
[PATCH v4 62/78] ncr5380: Implement new eh_bus_reset_handler Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:30 +0100
[PATCH v4 60/78] ncr5380: Implement new eh_abort_handler Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:30 +0100
[PATCH v4 51/78] ncr5380: Remove command list debug code Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:30 +0100
[PATCH v4 68/78] ncr5380: Fix trailing whitespace using regexp Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:30 +0100
[PATCH v4 38/78] ncr5380: Remove UNSAFE macro Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:30 +0100
[PATCH v4 46/78] ncr5380: Fix NDEBUG_NO_DATAOUT flag Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:30 +0100
[PATCH v4 47/78] ncr5380: Fix and cleanup scsi_host_template initializers Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:30 +0100
[PATCH v4 44/78] ncr5380: Fix off-by-one bug in extended_msg[] bounds check Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:30 +0100
[PATCH v4 55/78] ncr5380: Remove LIST and REMOVE macros Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:30 +0100
[PATCH v4 69/78] ncr5380: Fix whitespace in comments using regexp Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:30 +0100
Re: [PATCH v4 69/78] ncr5380: Fix whitespace in comments using regexp Joe Perches <joe@perches.com> - 2016-01-03 09:00 +0100
Re: [PATCH v4 69/78] ncr5380: Fix whitespace in comments using regexp Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 09:20 +0100
Re: [PATCH v4 69/78] ncr5380: Fix whitespace in comments using regexp One Thousand Gnomes <gnomes@lxorguk.ukuu.org.uk> - 2016-01-03 15:20 +0100
Re: [PATCH v4 69/78] ncr5380: Fix whitespace in comments using regexp Joe Perches <joe@perches.com> - 2016-01-03 19:30 +0100
Re: [PATCH v4 69/78] ncr5380: Fix whitespace in comments using regexp One Thousand Gnomes <gnomes@lxorguk.ukuu.org.uk> - 2016-01-03 22:40 +0100
Re: [PATCH v4 69/78] ncr5380: Fix whitespace in comments using regexp Joe Perches <joe@perches.com> - 2016-01-03 22:50 +0100
Re: [PATCH v4 69/78] ncr5380: Fix whitespace in comments using regexp Joe Perches <joe@perches.com> - 2016-01-03 23:20 +0100
[PATCH v4 71/78] atari_NCR5380: Merge changes from NCR5380.c Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:30 +0100
[PATCH v4 70/78] ncr5380: Merge changes from atari_NCR5380.c Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:30 +0100
[PATCH v4 52/78] ncr5380: Remove H_NO macro and introduce dsprintk Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:30 +0100
[PATCH v4 31/78] ncr5380: Fix !REQ timeout in do_abort() Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:30 +0100
[PATCH v4 74/78] ncr5380: Use runtime register mapping Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:30 +0100
[PATCH v4 76/78] ncr5380: Enable PDMA for DTC chips Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:30 +0100
[PATCH v4 67/78] ncr5380: Cleanup comments Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:30 +0100
[PATCH v4 39/78] ncr5380: Standardize interrupt handling Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:30 +0100
[PATCH v4 65/78] atari_scsi, sun3_scsi: Remove global Scsi_Host pointer Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:30 +0100
[PATCH v4 57/78] ncr5380: Use standard list data structure Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:30 +0100
[PATCH v4 42/78] ncr5380: Replace READ_OVERRUNS macro with FLAG_NO_DMA_FIXUPS Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:30 +0100
[PATCH v4 56/78] ncr5380: Remove redundant volatile qualifiers Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:30 +0100
[PATCH v4 59/78] ncr5380: Fix autosense bugs Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:30 +0100
[PATCH v4 45/78] ncr5380: Cleanup #include directives Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:30 +0100
[PATCH v4 75/78] ncr5380: Enable PDMA for NCR53C400A Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:30 +0100
[PATCH v4 48/78] atari_NCR5380: Fix queue_size limit Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:30 +0100
[PATCH v4 54/78] ncr5380: Use dsprintk() for queue debugging Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:30 +0100
[PATCH v4 08/78] ncr5380: Move NCR53C400-specific code Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:30 +0100
[PATCH v4 35/78] ncr5380: Dont wait for BUS FREE after disconnect Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:30 +0100
[PATCH v4 10/78] atari_NCR5380: Remove RESET_BOOT, CONFIG_ATARI_SCSI_TOSHIBA_DELAY and CONFIG_ATARI_SCSI_RESET_BOOT Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:30 +0100
[PATCH v4 58/78] ncr5380: Refactor command completion Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:30 +0100
[PATCH v4 64/78] atari_NCR5380: Eliminate HOSTNO macro Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:30 +0100
[PATCH v4 78/78] ncr5380: Add support for HP C2502 Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:30 +0100
[PATCH v4 72/78] ncr5380: Cleanup whitespace and parentheses Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:30 +0100
[PATCH v4 77/78] ncr5380: Fix wait for 53C80 registers registers after PDMA Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:30 +0100
[PATCH v4 61/78] ncr5380: Fix EH during arbitration and selection Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:30 +0100
[PATCH v4 03/78] ncr5380: Eliminate PDEBUG*, TDEBUG* and DTCDEBUG* macros Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:30 +0100
[PATCH v4 66/78] ncr5380: Fix soft lockups Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:30 +0100
[PATCH v4 32/78] ncr5380: Fix bus phase in do_abort() Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:40 +0100
[PATCH v4 06/78] ncr5380: Remove NCR5380_instance_name macro Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:40 +0100
[PATCH v4 34/78] atari_NCR5380: Use arbitration timeout Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:40 +0100
[PATCH v4 50/78] ncr5380: Change instance->host_lock to hostdata->lock Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:40 +0100
[PATCH v4 22/78] ncr5380: Eliminate selecting state Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:40 +0100
[PATCH v4 27/78] ncr5380: Add missing lock in eh_abort_handler Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:40 +0100
[PATCH v4 20/78] ncr5380: Introduce unbound workqueue Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:40 +0100
[PATCH v4 11/78] ncr5380: Simplify bus reset handlers Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:40 +0100
[PATCH v4 17/78] ncr5380: Keep BSY asserted when entering SELECTION phase Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:40 +0100
[PATCH v4 05/78] ncr5380: Remove NCR5380_local_declare and NCR5380_setup macros Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:40 +0100
[PATCH v4 37/78] ncr5380: Standardize work queueing algorithm Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:40 +0100
[PATCH v4 12/78] ncr5380: Remove unused hostdata->aborted flag Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:40 +0100
[PATCH v4 49/78] ncr5380: Remove redundant ICR_ARBITRATION_LOST test and eliminate FLAG_DTC3181E Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:40 +0100
[PATCH v4 28/78] ncr5380: Drop DEF_SCSI_QCMD macro Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:40 +0100
[PATCH v4 40/78] ncr5380: Introduce NCR5380_poll_politely2 Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:40 +0100
[PATCH v4 30/78] ncr5380: Add missing break after case MESSAGE_REJECT Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:40 +0100
[PATCH v4 43/78] ncr5380: Standardize reselection handling Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:40 +0100
[PATCH v4 26/78] ncr5380: Fix NCR5380_transfer_pio() result Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:40 +0100
[PATCH v4 19/78] ncr5380: Cleanup bogus {request,release}_region() calls Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:40 +0100
[PATCH v4 07/78] ncr5380: Split NCR5380_init() into two functions Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:40 +0100
[PATCH v4 36/78] ncr5380: Use work_struct instead of delayed_work Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:40 +0100
[PATCH v4 25/78] ncr5380: Rework disconnect versus poll logic Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:40 +0100
[PATCH v4 09/78] atari_NCR5380: Reset bus on driver initialization if required Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:40 +0100
[PATCH v4 41/78] ncr5380: Replace redundant flags with FLAG_NO_DMA_FIXUP Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:40 +0100
[PATCH v4 15/78] ncr5380: Always escalate bad target time-out in NCR5380_select() Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:50 +0100
[PATCH v4 01/78] atari_scsi: Fix SCSI host ID setting Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:50 +0100
[PATCH v4 16/78] ncr5380: Proceed with next command after NCR5380_select() calls scsi_done Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:50 +0100
[PATCH v4 14/78] ncr5380: Use return instead of goto in NCR5380_select() Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:50 +0100
[PATCH v4 04/78] ncr5380: Remove more pointless macros Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:50 +0100
[PATCH v4 18/78] ncr5380: Eliminate USLEEP_WAITLONG delay Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:50 +0100
[PATCH v4 02/78] ncr5380: Remove redundant static variable initializers Finn Thain <fthain@telegraphics.com.au> - 2016-01-03 06:50 +0100
Re: [PATCH v4 00/78] More fixes, cleanup and modernization for NCR5380 drivers "Martin K. Petersen" <martin.petersen@oracle.com> - 2016-01-07 04:00 +0100
Page 3 of 5 — ← Prev page 1 2 [3] 4 5 Next page →
| From | Finn Thain <fthain@telegraphics.com.au> |
|---|---|
| Date | 2016-01-03 06:30 +0100 |
| Subject | [PATCH v4 54/78] ncr5380: Use dsprintk() for queue debugging |
| Message-ID | <qMJoU-1cG-67@gated-at.bofh.it> |
| In reply to | #1300181 |
Print the command pointers in the log messages for debugging queue data
structures. The LIST and REMOVE macros can then be removed.
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Tested-by: Ondrej Zary <linux@rainbow-software.org>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
---
drivers/scsi/NCR5380.c | 36 ++++++++++++++++++++++++------------
drivers/scsi/atari_NCR5380.c | 43 +++++++++++++++++++++++--------------------
2 files changed, 47 insertions(+), 32 deletions(-)
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c 2016-01-03 16:04:15.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c 2016-01-03 16:04:17.000000000 +1100
@@ -936,10 +936,8 @@ static void NCR5380_main(struct work_str
prev = NULL; tmp; prev = tmp, tmp = NEXT(tmp)) {
u8 lun = tmp->device->lun;
- dprintk(NDEBUG_LISTS,
- "MAIN tmp=%p target=%d busy=%d lun=%d\n",
- tmp, scmd_id(tmp), hostdata->busy[scmd_id(tmp)],
- lun);
+ dsprintk(NDEBUG_QUEUES, instance, "main: tmp=%p target=%d busy=%d lun=%d\n",
+ tmp, scmd_id(tmp), hostdata->busy[scmd_id(tmp)], lun);
/* When we find one, remove it from the issue queue. */
if (
#ifdef SUPPORT_TAGS
@@ -956,6 +954,10 @@ static void NCR5380_main(struct work_str
hostdata->issue_queue = NEXT(tmp);
}
SET_NEXT(tmp, NULL);
+ dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES,
+ instance, "main: removed %p from issue queue %p\n",
+ tmp, prev);
+
hostdata->retain_dma_intr++;
/*
@@ -964,9 +966,6 @@ static void NCR5380_main(struct work_str
* On failure, we must add the command back to the
* issue queue so we can keep trying.
*/
- dprintk(NDEBUG_MAIN, "scsi%d: main(): command for target %d "
- "lun %d removed from issue_queue\n",
- HOSTNO, tmp->device->id, lun);
/*
* REQUEST SENSE commands are issued without tagged
* queueing, even on SCSI-II devices because the
@@ -989,13 +988,14 @@ static void NCR5380_main(struct work_str
LIST(tmp, hostdata->issue_queue);
SET_NEXT(tmp, hostdata->issue_queue);
hostdata->issue_queue = tmp;
+ dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES,
+ instance, "main: select() failed, %p returned to issue queue\n",
+ tmp);
#ifdef SUPPORT_TAGS
cmd_free_tag(tmp);
#endif
hostdata->retain_dma_intr--;
done = 0;
- dprintk(NDEBUG_MAIN, "scsi%d: main(): select() failed, "
- "returned to issue_queue\n", HOSTNO);
}
if (hostdata->connected)
break;
@@ -2017,8 +2017,9 @@ static void NCR5380_information_transfer
case COMMAND_COMPLETE:
/* Accept message by clearing ACK */
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
- dprintk(NDEBUG_QUEUES, "scsi%d: command for target %d, lun %llu "
- "completed\n", HOSTNO, cmd->device->id, cmd->device->lun);
+ dsprintk(NDEBUG_QUEUES, instance,
+ "COMMAND COMPLETE %p target %d lun %llu\n",
+ cmd, scmd_id(cmd), cmd->device->lun);
hostdata->connected = NULL;
#ifdef SUPPORT_TAGS
@@ -2067,13 +2068,11 @@ static void NCR5380_information_transfer
(status_byte(cmd->SCp.Status) == CHECK_CONDITION)) {
scsi_eh_prep_cmnd(cmd, &hostdata->ses, NULL, 0, ~0);
- dprintk(NDEBUG_AUTOSENSE, "scsi%d: performing request sense\n", HOSTNO);
-
LIST(cmd,hostdata->issue_queue);
SET_NEXT(cmd, hostdata->issue_queue);
hostdata->issue_queue = (struct scsi_cmnd *) cmd;
- dsprintk(NDEBUG_QUEUES, instance,
- "REQUEST SENSE cmd %p added to head of issue queue\n",
+ dsprintk(NDEBUG_AUTOSENSE | NDEBUG_QUEUES,
+ instance, "REQUEST SENSE cmd %p added to head of issue queue\n",
cmd);
} else {
cmd->scsi_done(cmd);
@@ -2124,10 +2123,10 @@ static void NCR5380_information_transfer
SET_NEXT(cmd, hostdata->disconnected_queue);
hostdata->connected = NULL;
hostdata->disconnected_queue = cmd;
- dprintk(NDEBUG_QUEUES, "scsi%d: command for target %d lun %llu was "
- "moved from connected to the "
- "disconnected_queue\n", HOSTNO,
- cmd->device->id, cmd->device->lun);
+ dsprintk(NDEBUG_INFORMATION | NDEBUG_QUEUES,
+ instance, "connected command %p for target %d lun %llu moved to disconnected queue\n",
+ cmd, scmd_id(cmd), cmd->device->lun);
+
/*
* Restore phase bits to 0 so an interrupted selection,
* arbitration can resume.
@@ -2427,7 +2426,11 @@ static void NCR5380_reselect(struct Scsi
}
}
- if (!tmp) {
+ if (tmp) {
+ dsprintk(NDEBUG_RESELECTION | NDEBUG_QUEUES, instance,
+ "reselect: removed %p from disconnected queue\n", tmp);
+ } else {
+
#ifdef SUPPORT_TAGS
shost_printk(KERN_ERR, instance, "target bitmask 0x%02x lun %d tag %d not in disconnected queue.\n",
target_mask, lun, tag);
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c 2016-01-03 16:04:15.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c 2016-01-03 16:04:17.000000000 +1100
@@ -828,8 +828,9 @@ static void NCR5380_main(struct work_str
*/
for (tmp = (struct scsi_cmnd *) hostdata->issue_queue, prev = NULL; tmp; prev = tmp, tmp = (struct scsi_cmnd *) tmp->host_scribble)
{
- if (prev != tmp)
- dprintk(NDEBUG_LISTS, "MAIN tmp=%p target=%d busy=%d lun=%llu\n", tmp, tmp->device->id, hostdata->busy[tmp->device->id], tmp->device->lun);
+ dsprintk(NDEBUG_QUEUES, instance, "main: tmp=%p target=%d busy=%d lun=%llu\n",
+ tmp, scmd_id(tmp), hostdata->busy[scmd_id(tmp)],
+ tmp->device->lun);
/* When we find one, remove it from the issue queue. */
if (!(hostdata->busy[tmp->device->id] &
(1 << (u8)(tmp->device->lun & 0xff)))) {
@@ -841,6 +842,9 @@ static void NCR5380_main(struct work_str
hostdata->issue_queue = (struct scsi_cmnd *) tmp->host_scribble;
}
tmp->host_scribble = NULL;
+ dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES,
+ instance, "main: removed %p from issue queue %p\n",
+ tmp, prev);
/*
* Attempt to establish an I_T_L nexus here.
@@ -848,8 +852,6 @@ static void NCR5380_main(struct work_str
* On failure, we must add the command back to the
* issue queue so we can keep trying.
*/
- dprintk(NDEBUG_MAIN|NDEBUG_QUEUES, "scsi%d : main() : command for target %d lun %llu removed from issue_queue\n", instance->host_no, tmp->device->id, tmp->device->lun);
-
/*
* REQUEST SENSE commands are issued without tagged
* queueing, even on SCSI-II devices because the
@@ -864,8 +866,10 @@ static void NCR5380_main(struct work_str
LIST(tmp, hostdata->issue_queue);
tmp->host_scribble = (unsigned char *) hostdata->issue_queue;
hostdata->issue_queue = tmp;
+ dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES,
+ instance, "main: select() failed, %p returned to issue queue\n",
+ tmp);
done = 0;
- dprintk(NDEBUG_MAIN|NDEBUG_QUEUES, "scsi%d : main(): select() failed, returned to issue_queue\n", instance->host_no);
}
if (hostdata->connected)
break;
@@ -1847,8 +1851,11 @@ static void NCR5380_information_transfer
/* Accept message by clearing ACK */
sink = 1;
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+ dsprintk(NDEBUG_QUEUES, instance,
+ "COMMAND COMPLETE %p target %d lun %llu\n",
+ cmd, scmd_id(cmd), cmd->device->lun);
+
hostdata->connected = NULL;
- dprintk(NDEBUG_QUEUES, "scsi%d : command for target %d, lun %llu completed\n", instance->host_no, cmd->device->id, cmd->device->lun);
hostdata->busy[cmd->device->id] &= ~(1 << (cmd->device->lun & 0xFF));
/*
@@ -1881,14 +1888,12 @@ static void NCR5380_information_transfer
if ((cmd->cmnd[0] != REQUEST_SENSE) && (status_byte(cmd->SCp.Status) == CHECK_CONDITION)) {
scsi_eh_prep_cmnd(cmd, &hostdata->ses, NULL, 0, ~0);
- dprintk(NDEBUG_AUTOSENSE, "scsi%d : performing request sense\n", instance->host_no);
-
LIST(cmd, hostdata->issue_queue);
cmd->host_scribble = (unsigned char *)
hostdata->issue_queue;
hostdata->issue_queue = (struct scsi_cmnd *) cmd;
- dsprintk(NDEBUG_QUEUES, instance,
- "REQUEST SENSE cmd %p added to head of issue queue\n",
+ dsprintk(NDEBUG_AUTOSENSE | NDEBUG_QUEUES,
+ instance, "REQUEST SENSE cmd %p added to head of issue queue\n",
cmd);
} else {
cmd->scsi_done(cmd);
@@ -1925,7 +1930,10 @@ static void NCR5380_information_transfer
hostdata->disconnected_queue;
hostdata->connected = NULL;
hostdata->disconnected_queue = cmd;
- dprintk(NDEBUG_QUEUES, "scsi%d : command for target %d lun %llu was moved from connected to" " the disconnected_queue\n", instance->host_no, cmd->device->id, cmd->device->lun);
+ dsprintk(NDEBUG_INFORMATION | NDEBUG_QUEUES,
+ instance, "connected command %p for target %d lun %llu moved to disconnected queue\n",
+ cmd, scmd_id(cmd), cmd->device->lun);
+
/*
* Restore phase bits to 0 so an interrupted selection,
* arbitration can resume.
@@ -2178,7 +2186,11 @@ static void NCR5380_reselect(struct Scsi
break;
}
}
- if (!tmp) {
+
+ if (tmp) {
+ dsprintk(NDEBUG_RESELECTION | NDEBUG_QUEUES, instance,
+ "reselect: removed %p from disconnected queue\n", tmp);
+ } else {
shost_printk(KERN_ERR, instance, "target bitmask 0x%02x lun %d not in disconnected queue.\n",
target_mask, lun);
/*
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Finn Thain <fthain@telegraphics.com.au> |
|---|---|
| Date | 2016-01-03 06:30 +0100 |
| Subject | [PATCH v4 08/78] ncr5380: Move NCR53C400-specific code |
| Message-ID | <qMJoV-1cG-69@gated-at.bofh.it> |
| In reply to | #1300181 |
Move board-specific code like this,
NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);
from the core driver to the board driver. Eliminate the NCR53C400 macro
from the core driver. Removal of all macros like this one will be
necessary in order to have one core driver that can support all kinds of
boards.
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Tested-by: Ondrej Zary <linux@rainbow-software.org>
---
Changed since v1:
- Don't set FLAG_NO_PSEUDO_DMA when !defined(PSEUDO_DMA). It's pointless.
---
drivers/scsi/NCR5380.c | 18 ------------------
drivers/scsi/g_NCR5380.c | 21 ++++++++++++++++-----
drivers/scsi/g_NCR5380.h | 6 ++----
3 files changed, 18 insertions(+), 27 deletions(-)
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c 2016-01-03 16:03:03.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c 2016-01-03 16:03:06.000000000 +1100
@@ -654,9 +654,6 @@ static void prepare_info(struct Scsi_Hos
#ifdef UNSAFE
"UNSAFE "
#endif
-#ifdef NCR53C400
- "NCR53C400 "
-#endif
"");
}
@@ -782,15 +779,6 @@ static int NCR5380_init(struct Scsi_Host
if(in_interrupt())
printk(KERN_ERR "NCR5380_init called with interrupts off!\n");
- /*
- * On NCR53C400 boards, NCR5380 registers are mapped 8 past
- * the base address.
- */
-
-#ifdef NCR53C400
- if (flags & FLAG_NCR53C400)
- instance->io_port += NCR53C400_address_adjust;
-#endif
hostdata->aborted = 0;
hostdata->id_mask = 1 << instance->this_id;
@@ -824,12 +812,6 @@ static int NCR5380_init(struct Scsi_Host
NCR5380_write(MODE_REG, MR_BASE);
NCR5380_write(TARGET_COMMAND_REG, 0);
NCR5380_write(SELECT_ENABLE_REG, 0);
-
-#ifdef NCR53C400
- if (hostdata->flags & FLAG_NCR53C400) {
- NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);
- }
-#endif
return 0;
}
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c 2016-01-03 16:03:03.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c 2016-01-03 16:03:06.000000000 +1100
@@ -64,9 +64,7 @@
#define AUTOPROBE_IRQ
#ifdef CONFIG_SCSI_GENERIC_NCR53C400
-#define NCR53C400_PSEUDO_DMA 1
#define PSEUDO_DMA
-#define NCR53C400
#endif
#include <asm/io.h>
@@ -263,7 +261,7 @@ static int __init generic_NCR5380_detect
static unsigned int __initdata dtc_3181e_ports[] = {
0x220, 0x240, 0x280, 0x2a0, 0x2c0, 0x300, 0x320, 0x340, 0
};
- int flags = 0;
+ int flags;
struct Scsi_Host *instance;
#ifdef SCSI_G_NCR5380_MEM
unsigned long base;
@@ -324,12 +322,15 @@ static int __init generic_NCR5380_detect
continue;
ports = NULL;
+ flags = 0;
switch (overrides[current_override].board) {
case BOARD_NCR5380:
flags = FLAG_NO_PSEUDO_DMA;
break;
case BOARD_NCR53C400:
+#ifdef PSEUDO_DMA
flags = FLAG_NCR53C400;
+#endif
break;
case BOARD_NCR53C400A:
flags = FLAG_NO_PSEUDO_DMA;
@@ -415,6 +416,13 @@ static int __init generic_NCR5380_detect
#ifndef SCSI_G_NCR5380_MEM
instance->io_port = overrides[current_override].NCR5380_map_name;
instance->n_io_port = region_size;
+
+ /*
+ * On NCR53C400 boards, NCR5380 registers are mapped 8 past
+ * the base address.
+ */
+ if (overrides[current_override].board == BOARD_NCR53C400)
+ instance->io_port += 8;
#else
instance->base = overrides[current_override].NCR5380_map_name;
((struct NCR5380_hostdata *)instance->hostdata)->iomem = iomem;
@@ -422,6 +430,9 @@ static int __init generic_NCR5380_detect
NCR5380_init(instance, flags);
+ if (overrides[current_override].board == BOARD_NCR53C400)
+ NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);
+
NCR5380_maybe_reset_bus(instance);
if (overrides[current_override].irq != IRQ_AUTO)
@@ -506,7 +517,7 @@ generic_NCR5380_biosparam(struct scsi_de
}
#endif
-#ifdef NCR53C400_PSEUDO_DMA
+#ifdef PSEUDO_DMA
/**
* NCR5380_pread - pseudo DMA read
@@ -690,7 +701,7 @@ static inline int NCR5380_pwrite(struct
; // TIMEOUT
return 0;
}
-#endif /* PSEUDO_DMA */
+#endif /* PSEUDO_DMA */
/*
* Include the NCR5380 core code that we build our driver around
Index: linux/drivers/scsi/g_NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.h 2016-01-03 16:03:02.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.h 2016-01-03 16:03:06.000000000 +1100
@@ -14,7 +14,7 @@
#ifndef GENERIC_NCR5380_H
#define GENERIC_NCR5380_H
-#ifdef NCR53C400
+#ifdef CONFIG_SCSI_GENERIC_NCR53C400
#define BIOSPARAM
#define NCR5380_BIOSPARAM generic_NCR5380_biosparam
#else
@@ -37,9 +37,8 @@
#define NCR5380_map_type int
#define NCR5380_map_name port
#define NCR53C400_register_offset 0
-#define NCR53C400_address_adjust 8
-#ifdef NCR53C400
+#ifdef CONFIG_SCSI_GENERIC_NCR53C400
#define NCR5380_region_size 16
#else
#define NCR5380_region_size 8
@@ -58,7 +57,6 @@
#define NCR5380_map_type unsigned long
#define NCR5380_map_name base
#define NCR53C400_register_offset 0x108
-#define NCR53C400_address_adjust 0
#define NCR53C400_mem_base 0x3880
#define NCR53C400_host_buffer 0x3900
#define NCR5380_region_size 0x3a00
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Finn Thain <fthain@telegraphics.com.au> |
|---|---|
| Date | 2016-01-03 06:30 +0100 |
| Subject | [PATCH v4 35/78] ncr5380: Dont wait for BUS FREE after disconnect |
| Message-ID | <qMJoV-1cG-77@gated-at.bofh.it> |
| In reply to | #1300181 |
When there is a queued command and no connected command, NCR5380_select() is called and arbitration begins. The chip waits for BUS FREE once the MR_ARBITRATE bit in the mode register is enabled. That means there is no need to wait for BUS FREE after disconnecting. There is presently no polling for BUS FREE after sending an ABORT or other message that might lead to disconnection. It only happens after COMMAND COMPLETE or DISCONNECT messages, which seems inconsistent. Remove the polling for !BSY in the COMMAND COMPLETE and DISCONNECT cases. BTW, the comments say "avoid nasty timeouts" and perhaps BUS FREE polling was somehow helpful back in Linux v0.99.14u, when it was introduced. The relevant timeout is presently 1 second (for bus arbitration). Signed-off-by: Finn Thain <fthain@telegraphics.com.au> Reviewed-by: Hannes Reinecke <hare@suse.com> Tested-by: Ondrej Zary <linux@rainbow-software.org> Tested-by: Michael Schmitz <schmitzmic@gmail.com> --- drivers/scsi/NCR5380.c | 7 ------- drivers/scsi/atari_NCR5380.c | 11 ----------- 2 files changed, 18 deletions(-) Index: linux/drivers/scsi/NCR5380.c =================================================================== --- linux.orig/drivers/scsi/NCR5380.c 2016-01-03 16:03:44.000000000 +1100 +++ linux/drivers/scsi/NCR5380.c 2016-01-03 16:03:46.000000000 +1100 @@ -1976,9 +1976,6 @@ static void NCR5380_information_transfer * arbitration can resume. */ NCR5380_write(TARGET_COMMAND_REG, 0); - - while ((NCR5380_read(STATUS_REG) & SR_BSY) && !hostdata->connected) - barrier(); return; case MESSAGE_REJECT: /* Accept message by clearing ACK */ @@ -2011,10 +2008,6 @@ static void NCR5380_information_transfer /* Enable reselect interrupts */ NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); - /* Wait for bus free to avoid nasty timeouts - FIXME timeout !*/ - /* NCR538_poll_politely(instance, STATUS_REG, SR_BSY, 0, 30 * HZ); */ - while ((NCR5380_read(STATUS_REG) & SR_BSY) && !hostdata->connected) - barrier(); return; } /* Index: linux/drivers/scsi/atari_NCR5380.c =================================================================== --- linux.orig/drivers/scsi/atari_NCR5380.c 2016-01-03 16:03:44.000000000 +1100 +++ linux/drivers/scsi/atari_NCR5380.c 2016-01-03 16:03:46.000000000 +1100 @@ -2213,7 +2213,6 @@ static void NCR5380_information_transfer "completed\n", HOSTNO, cmd->device->id, cmd->device->lun); local_irq_save(flags); - hostdata->retain_dma_intr++; hostdata->connected = NULL; #ifdef SUPPORT_TAGS cmd_free_tag(cmd); @@ -2282,8 +2281,6 @@ static void NCR5380_information_transfer cmd->scsi_done(cmd); } - local_irq_restore(flags); - NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); /* * Restore phase bits to 0 so an interrupted selection, @@ -2291,11 +2288,6 @@ static void NCR5380_information_transfer */ NCR5380_write(TARGET_COMMAND_REG, 0); - while ((NCR5380_read(STATUS_REG) & SR_BSY) && !hostdata->connected) - barrier(); - - local_irq_save(flags); - hostdata->retain_dma_intr--; /* ++roman: For Falcon SCSI, release the lock on the * ST-DMA here if no other commands are waiting on the * disconnected queue. @@ -2349,9 +2341,6 @@ static void NCR5380_information_transfer /* Enable reselect interrupts */ NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); - /* Wait for bus free to avoid nasty timeouts */ - while ((NCR5380_read(STATUS_REG) & SR_BSY) && !hostdata->connected) - barrier(); #ifdef SUN3_SCSI_VME dregs->csr |= CSR_DMA_ENABLE; #endif -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Finn Thain <fthain@telegraphics.com.au> |
|---|---|
| Date | 2016-01-03 06:30 +0100 |
| Subject | [PATCH v4 10/78] atari_NCR5380: Remove RESET_BOOT, CONFIG_ATARI_SCSI_TOSHIBA_DELAY and CONFIG_ATARI_SCSI_RESET_BOOT |
| Message-ID | <qMJoV-1cG-75@gated-at.bofh.it> |
| In reply to | #1300181 |
The atari_NCR5380.c core driver now takes care of bus reset upon driver
initialization if required (same as NCR5380.c). Move the Toshiba CD-ROM
support into the core driver, enabled with a host flag, so that all
NCR5380 drivers can make use of it.
Drop the RESET_BOOT macros and the ATARI_SCSI_RESET_BOOT and
ATARI_SCSI_TOSHIBA_DELAY Kconfig symbols, which are now redundant.
Remove the atari_scsi_reset_boot(), mac_scsi_reset_boot() and
sun3_scsi_reset_boot() routines. None of this duplicated code is needed
now that all drivers can use NCR5380_maybe_reset_bus().
This brings atari_scsi, mac_scsi and sun3_scsi into line with all of the
other NCR5380 drivers.
The bus reset may raise an interrupt. That would be new behaviour for
atari_scsi only when CONFIG_ATARI_SCSI_RESET_BOOT=n. The ST DMA interrupt
is not assigned to atari_scsi at this stage, so
CONFIG_ATARI_SCSI_RESET_BOOT=y may well be problematic already.
Regardless, do_reset() now raises and clears the interrupt within
local_irq_save/restore which should avoid problems.
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Tested-by: Ondrej Zary <linux@rainbow-software.org>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
---
Changed since v1:
- Fixed minor inconsistency in mac5380= usage message.
---
drivers/scsi/Kconfig | 17 -----------
drivers/scsi/NCR5380.c | 17 +++++++++--
drivers/scsi/NCR5380.h | 1
drivers/scsi/atari_NCR5380.c | 22 +++++++++-----
drivers/scsi/atari_scsi.c | 60 +++++----------------------------------
drivers/scsi/mac_scsi.c | 65 ++++++-------------------------------------
drivers/scsi/sun3_scsi.c | 47 -------------------------------
7 files changed, 51 insertions(+), 178 deletions(-)
Index: linux/drivers/scsi/Kconfig
===================================================================
--- linux.orig/drivers/scsi/Kconfig 2016-01-03 16:02:37.000000000 +1100
+++ linux/drivers/scsi/Kconfig 2016-01-03 16:03:09.000000000 +1100
@@ -1618,23 +1618,6 @@ config ATARI_SCSI
ST-DMA, replacing ACSI). It does NOT support other schemes, like
in the Hades (without DMA).
-config ATARI_SCSI_TOSHIBA_DELAY
- bool "Long delays for Toshiba CD-ROMs"
- depends on ATARI_SCSI
- help
- This option increases the delay after a SCSI arbitration to
- accommodate some flaky Toshiba CD-ROM drives. Say Y if you intend to
- use a Toshiba CD-ROM drive; otherwise, the option is not needed and
- would impact performance a bit, so say N.
-
-config ATARI_SCSI_RESET_BOOT
- bool "Reset SCSI-devices at boottime"
- depends on ATARI_SCSI
- help
- Reset the devices on your Atari whenever it boots. This makes the
- boot process fractionally longer but may assist recovery from errors
- that leave the devices with SCSI operations partway completed.
-
config MAC_SCSI
tristate "Macintosh NCR5380 SCSI"
depends on MAC && SCSI=y
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c 2016-01-03 16:03:08.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c 2016-01-03 16:03:09.000000000 +1100
@@ -674,13 +674,14 @@ static void prepare_info(struct Scsi_Hos
"base 0x%lx, irq %d, "
"can_queue %d, cmd_per_lun %d, "
"sg_tablesize %d, this_id %d, "
- "flags { %s}, "
+ "flags { %s%s}, "
"options { %s} ",
instance->hostt->name, instance->io_port, instance->n_io_port,
instance->base, instance->irq,
instance->can_queue, instance->cmd_per_lun,
instance->sg_tablesize, instance->this_id,
hostdata->flags & FLAG_TAGGED_QUEUING ? "TAGGED_QUEUING " : "",
+ hostdata->flags & FLAG_TOSHIBA_DELAY ? "TOSHIBA_DELAY " : "",
#ifdef DIFFERENTIAL
"DIFFERENTIAL "
#endif
@@ -860,6 +861,7 @@ static int __init NCR5380_init(struct Sc
static int NCR5380_maybe_reset_bus(struct Scsi_Host *instance)
{
+ struct NCR5380_hostdata *hostdata = shost_priv(instance);
int pass;
for (pass = 1; (NCR5380_read(STATUS_REG) & SR_BSY) && pass <= 6; ++pass) {
@@ -878,6 +880,14 @@ static int NCR5380_maybe_reset_bus(struc
case 4:
shost_printk(KERN_ERR, instance, "bus busy, attempting reset\n");
do_reset(instance);
+ /* Wait after a reset; the SCSI standard calls for
+ * 250ms, we wait 500ms to be on the safe side.
+ * But some Toshiba CD-ROMs need ten times that.
+ */
+ if (hostdata->flags & FLAG_TOSHIBA_DELAY)
+ msleep(2500);
+ else
+ msleep(500);
break;
case 6:
shost_printk(KERN_ERR, instance, "bus locked solid\n");
@@ -1493,12 +1503,10 @@ static int NCR5380_select(struct Scsi_Ho
* a minimum so we'll udelay ceil(1.2)
*/
-#ifdef CONFIG_ATARI_SCSI_TOSHIBA_DELAY
- /* ++roman: But some targets (see above :-) seem to need a bit more... */
- udelay(15);
-#else
- udelay(2);
-#endif
+ if (hostdata->flags & FLAG_TOSHIBA_DELAY)
+ udelay(15);
+ else
+ udelay(2);
if (hostdata->connected) {
NCR5380_write(MODE_REG, MR_BASE);
Index: linux/drivers/scsi/atari_scsi.c
===================================================================
--- linux.orig/drivers/scsi/atari_scsi.c 2016-01-03 16:02:40.000000000 +1100
+++ linux/drivers/scsi/atari_scsi.c 2016-01-03 16:03:09.000000000 +1100
@@ -164,15 +164,6 @@ static inline unsigned long SCSI_DMA_GET
#define HOSTDATA_DMALEN (((struct NCR5380_hostdata *) \
(atari_scsi_host->hostdata))->dma_len)
-/* Time (in jiffies) to wait after a reset; the SCSI standard calls for 250ms,
- * we usually do 0.5s to be on the safe side. But Toshiba CD-ROMs once more
- * need ten times the standard value... */
-#ifndef CONFIG_ATARI_SCSI_TOSHIBA_DELAY
-#define AFTER_RESET_DELAY (HZ/2)
-#else
-#define AFTER_RESET_DELAY (5*HZ/2)
-#endif
-
#ifdef REAL_DMA
static void atari_scsi_fetch_restbytes(void);
#endif
@@ -208,12 +199,12 @@ static int setup_cmd_per_lun = -1;
module_param(setup_cmd_per_lun, int, 0);
static int setup_sg_tablesize = -1;
module_param(setup_sg_tablesize, int, 0);
-#ifdef SUPPORT_TAGS
static int setup_use_tagged_queuing = -1;
module_param(setup_use_tagged_queuing, int, 0);
-#endif
static int setup_hostid = -1;
module_param(setup_hostid, int, 0);
+static int setup_toshiba_delay = -1;
+module_param(setup_toshiba_delay, int, 0);
#if defined(REAL_DMA)
@@ -488,7 +479,7 @@ static int __init atari_scsi_setup(char
* Defaults depend on TT or Falcon, determined at run time.
* Negative values mean don't change.
*/
- int ints[6];
+ int ints[8];
get_options(str, ARRAY_SIZE(ints), ints);
@@ -504,10 +495,11 @@ static int __init atari_scsi_setup(char
setup_sg_tablesize = ints[3];
if (ints[0] >= 4)
setup_hostid = ints[4];
-#ifdef SUPPORT_TAGS
if (ints[0] >= 5)
setup_use_tagged_queuing = ints[5];
-#endif
+ /* ints[6] (use_pdma) is ignored */
+ if (ints[0] >= 7)
+ setup_toshiba_delay = ints[7];
return 1;
}
@@ -516,38 +508,6 @@ __setup("atascsi=", atari_scsi_setup);
#endif /* !MODULE */
-#ifdef CONFIG_ATARI_SCSI_RESET_BOOT
-static void __init atari_scsi_reset_boot(void)
-{
- unsigned long end;
-
- /*
- * Do a SCSI reset to clean up the bus during initialization. No messing
- * with the queues, interrupts, or locks necessary here.
- */
-
- printk("Atari SCSI: resetting the SCSI bus...");
-
- /* get in phase */
- NCR5380_write(TARGET_COMMAND_REG,
- PHASE_SR_TO_TCR(NCR5380_read(STATUS_REG)));
-
- /* assert RST */
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST);
- /* The min. reset hold time is 25us, so 40us should be enough */
- udelay(50);
- /* reset RST and interrupt */
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
- NCR5380_read(RESET_PARITY_INTERRUPT_REG);
-
- end = jiffies + AFTER_RESET_DELAY;
- while (time_before(jiffies, end))
- barrier();
-
- printk(" done\n");
-}
-#endif
-
#if defined(REAL_DMA)
static unsigned long atari_scsi_dma_setup(struct Scsi_Host *instance,
@@ -917,17 +877,13 @@ static int __init atari_scsi_probe(struc
}
atari_scsi_host = instance;
-#ifdef CONFIG_ATARI_SCSI_RESET_BOOT
- atari_scsi_reset_boot();
-#endif
-
instance->irq = irq->start;
host_flags |= IS_A_TT() ? 0 : FLAG_LATE_DMA_SETUP;
-
#ifdef SUPPORT_TAGS
host_flags |= setup_use_tagged_queuing > 0 ? FLAG_TAGGED_QUEUING : 0;
#endif
+ host_flags |= setup_toshiba_delay > 0 ? FLAG_TOSHIBA_DELAY : 0;
NCR5380_init(instance, host_flags);
@@ -975,6 +931,8 @@ static int __init atari_scsi_probe(struc
#endif
}
+ NCR5380_maybe_reset_bus(instance);
+
error = scsi_add_host(instance, NULL);
if (error)
goto fail_host;
Index: linux/drivers/scsi/mac_scsi.c
===================================================================
--- linux.orig/drivers/scsi/mac_scsi.c 2016-01-03 16:02:56.000000000 +1100
+++ linux/drivers/scsi/mac_scsi.c 2016-01-03 16:03:09.000000000 +1100
@@ -49,8 +49,6 @@
#include "NCR5380.h"
-#define RESET_BOOT
-
static int setup_can_queue = -1;
module_param(setup_can_queue, int, 0);
static int setup_cmd_per_lun = -1;
@@ -63,17 +61,8 @@ static int setup_use_tagged_queuing = -1
module_param(setup_use_tagged_queuing, int, 0);
static int setup_hostid = -1;
module_param(setup_hostid, int, 0);
-
-/* Time (in jiffies) to wait after a reset; the SCSI standard calls for 250ms,
- * we usually do 0.5s to be on the safe side. But Toshiba CD-ROMs once more
- * need ten times the standard value... */
-#define TOSHIBA_DELAY
-
-#ifdef TOSHIBA_DELAY
-#define AFTER_RESET_DELAY (5*HZ/2)
-#else
-#define AFTER_RESET_DELAY (HZ/2)
-#endif
+static int setup_toshiba_delay = -1;
+module_param(setup_toshiba_delay, int, 0);
/*
* NCR 5380 register access functions
@@ -92,12 +81,12 @@ static inline void macscsi_write(struct
#ifndef MODULE
static int __init mac_scsi_setup(char *str)
{
- int ints[7];
+ int ints[8];
(void)get_options(str, ARRAY_SIZE(ints), ints);
- if (ints[0] < 1 || ints[0] > 6) {
- pr_err("Usage: mac5380=<can_queue>[,<cmd_per_lun>[,<sg_tablesize>[,<hostid>[,<use_tags>[,<use_pdma>]]]]]\n");
+ if (ints[0] < 1) {
+ pr_err("Usage: mac5380=<can_queue>[,<cmd_per_lun>[,<sg_tablesize>[,<hostid>[,<use_tags>[,<use_pdma>[,<toshiba_delay>]]]]]]\n");
return 0;
}
if (ints[0] >= 1)
@@ -112,47 +101,14 @@ static int __init mac_scsi_setup(char *s
setup_use_tagged_queuing = ints[5];
if (ints[0] >= 6)
setup_use_pdma = ints[6];
+ if (ints[0] >= 7)
+ setup_toshiba_delay = ints[7];
return 1;
}
__setup("mac5380=", mac_scsi_setup);
#endif /* !MODULE */
-#ifdef RESET_BOOT
-/*
- * Our 'bus reset on boot' function
- */
-
-static void mac_scsi_reset_boot(struct Scsi_Host *instance)
-{
- unsigned long end;
-
- /*
- * Do a SCSI reset to clean up the bus during initialization. No messing
- * with the queues, interrupts, or locks necessary here.
- */
-
- printk(KERN_INFO "Macintosh SCSI: resetting the SCSI bus..." );
-
- /* get in phase */
- NCR5380_write( TARGET_COMMAND_REG,
- PHASE_SR_TO_TCR( NCR5380_read(STATUS_REG) ));
-
- /* assert RST */
- NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST );
- /* The min. reset hold time is 25us, so 40us should be enough */
- udelay( 50 );
- /* reset RST and interrupt */
- NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE );
- NCR5380_read( RESET_PARITY_INTERRUPT_REG );
-
- for( end = jiffies + AFTER_RESET_DELAY; time_before(jiffies, end); )
- barrier();
-
- printk(KERN_INFO " done\n" );
-}
-#endif
-
#ifdef PSEUDO_DMA
/*
Pseudo-DMA: (Ove Edlund)
@@ -421,13 +377,10 @@ static int __init mac_scsi_probe(struct
} else
host_flags |= FLAG_NO_PSEUDO_DMA;
-#ifdef RESET_BOOT
- mac_scsi_reset_boot(instance);
-#endif
-
#ifdef SUPPORT_TAGS
host_flags |= setup_use_tagged_queuing > 0 ? FLAG_TAGGED_QUEUING : 0;
#endif
+ host_flags |= setup_toshiba_delay > 0 ? FLAG_TOSHIBA_DELAY : 0;
NCR5380_init(instance, host_flags);
@@ -438,6 +391,8 @@ static int __init mac_scsi_probe(struct
goto fail_irq;
}
+ NCR5380_maybe_reset_bus(instance);
+
error = scsi_add_host(instance, NULL);
if (error)
goto fail_host;
Index: linux/drivers/scsi/sun3_scsi.c
===================================================================
--- linux.orig/drivers/scsi/sun3_scsi.c 2016-01-03 16:02:42.000000000 +1100
+++ linux/drivers/scsi/sun3_scsi.c 2016-01-03 16:03:09.000000000 +1100
@@ -86,10 +86,6 @@ module_param(setup_use_tagged_queuing, i
static int setup_hostid = -1;
module_param(setup_hostid, int, 0);
-/* #define RESET_BOOT */
-
-#define AFTER_RESET_DELAY (HZ/2)
-
/* ms to wait after hitting dma regs */
#define SUN3_DMA_DELAY 10
@@ -144,45 +140,6 @@ static inline void sun3_udc_write(unsign
}
#endif
-#ifdef RESET_BOOT
-static void sun3_scsi_reset_boot(struct Scsi_Host *instance)
-{
- unsigned long end;
-
- /*
- * Do a SCSI reset to clean up the bus during initialization. No
- * messing with the queues, interrupts, or locks necessary here.
- */
-
- printk( "Sun3 SCSI: resetting the SCSI bus..." );
-
- /* switch off SCSI IRQ - catch an interrupt without IRQ bit set else */
-// sun3_disable_irq( IRQ_SUN3_SCSI );
-
- /* get in phase */
- NCR5380_write( TARGET_COMMAND_REG,
- PHASE_SR_TO_TCR( NCR5380_read(STATUS_REG) ));
-
- /* assert RST */
- NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST );
-
- /* The min. reset hold time is 25us, so 40us should be enough */
- udelay( 50 );
-
- /* reset RST and interrupt */
- NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE );
- NCR5380_read( RESET_PARITY_INTERRUPT_REG );
-
- for( end = jiffies + AFTER_RESET_DELAY; time_before(jiffies, end); )
- barrier();
-
- /* switch on SCSI IRQ again */
-// sun3_enable_irq( IRQ_SUN3_SCSI );
-
- printk( " done\n" );
-}
-#endif
-
// safe bits for the CSR
#define CSR_GOOD 0x060f
@@ -631,9 +588,7 @@ static int __init sun3_scsi_probe(struct
dregs->ivect = VME_DATA24 | (instance->irq & 0xff);
#endif
-#ifdef RESET_BOOT
- sun3_scsi_reset_boot(instance);
-#endif
+ NCR5380_maybe_reset_bus(instance);
error = scsi_add_host(instance, NULL);
if (error)
Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h 2016-01-03 16:03:03.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h 2016-01-03 16:03:09.000000000 +1100
@@ -243,6 +243,7 @@
#define FLAG_DTC3181E 16 /* DTC3181E */
#define FLAG_LATE_DMA_SETUP 32 /* Setup NCR before DMA H/W */
#define FLAG_TAGGED_QUEUING 64 /* as X3T9.2 spelled it */
+#define FLAG_TOSHIBA_DELAY 128 /* Allow for borken CD-ROMs */
#ifdef SUPPORT_TAGS
struct tag_alloc {
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c 2016-01-03 16:03:08.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c 2016-01-03 16:03:09.000000000 +1100
@@ -618,7 +618,7 @@ static void prepare_info(struct Scsi_Hos
"base 0x%lx, irq %d, "
"can_queue %d, cmd_per_lun %d, "
"sg_tablesize %d, this_id %d, "
- "flags { %s%s%s}, "
+ "flags { %s%s%s%s}, "
#if defined(USLEEP_POLL) && defined(USLEEP_WAITLONG)
"USLEEP_POLL %lu, USLEEP_WAITLONG %lu, "
#endif
@@ -630,6 +630,7 @@ static void prepare_info(struct Scsi_Hos
hostdata->flags & FLAG_NCR53C400 ? "NCR53C400 " : "",
hostdata->flags & FLAG_DTC3181E ? "DTC3181E " : "",
hostdata->flags & FLAG_NO_PSEUDO_DMA ? "NO_PSEUDO_DMA " : "",
+ hostdata->flags & FLAG_TOSHIBA_DELAY ? "TOSHIBA_DELAY " : "",
#if defined(USLEEP_POLL) && defined(USLEEP_WAITLONG)
USLEEP_POLL, USLEEP_WAITLONG,
#endif
@@ -831,6 +832,7 @@ static int NCR5380_init(struct Scsi_Host
static int NCR5380_maybe_reset_bus(struct Scsi_Host *instance)
{
+ struct NCR5380_hostdata *hostdata = shost_priv(instance);
int pass;
for (pass = 1; (NCR5380_read(STATUS_REG) & SR_BSY) && pass <= 6; ++pass) {
@@ -849,6 +851,14 @@ static int NCR5380_maybe_reset_bus(struc
case 4:
shost_printk(KERN_ERR, instance, "bus busy, attempting reset\n");
do_reset(instance);
+ /* Wait after a reset; the SCSI standard calls for
+ * 250ms, we wait 500ms to be on the safe side.
+ * But some Toshiba CD-ROMs need ten times that.
+ */
+ if (hostdata->flags & FLAG_TOSHIBA_DELAY)
+ msleep(2500);
+ else
+ msleep(500);
break;
case 6:
shost_printk(KERN_ERR, instance, "bus locked solid\n");
@@ -1253,7 +1263,10 @@ static int NCR5380_select(struct Scsi_Ho
* a minimum so we'll udelay ceil(1.2)
*/
- udelay(2);
+ if (hostdata->flags & FLAG_TOSHIBA_DELAY)
+ udelay(15);
+ else
+ udelay(2);
dprintk(NDEBUG_ARBITRATION, "scsi%d : won arbitration\n", instance->host_no);
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Finn Thain <fthain@telegraphics.com.au> |
|---|---|
| Date | 2016-01-03 06:30 +0100 |
| Subject | [PATCH v4 58/78] ncr5380: Refactor command completion |
| Message-ID | <qMJoV-1cG-83@gated-at.bofh.it> |
| In reply to | #1300181 |
Implement a 'complete_cmd' function to complete commands. This is needed
by the following patch; the new function provides a site for the logic
needed to correctly handle REQUEST SENSE commands.
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Tested-by: Ondrej Zary <linux@rainbow-software.org>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
---
drivers/scsi/NCR5380.c | 31 ++++++++++++++++++++++------
drivers/scsi/atari_NCR5380.c | 46 ++++++++++++++++++++++++++++---------------
2 files changed, 55 insertions(+), 22 deletions(-)
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c 2016-01-03 16:04:20.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c 2016-01-03 16:04:24.000000000 +1100
@@ -765,6 +765,27 @@ static void NCR5380_exit(struct Scsi_Hos
}
/**
+ * complete_cmd - finish processing a command and return it to the SCSI ML
+ * @instance: the host instance
+ * @cmd: command to complete
+ */
+
+static void complete_cmd(struct Scsi_Host *instance,
+ struct scsi_cmnd *cmd)
+{
+ struct NCR5380_hostdata *hostdata = shost_priv(instance);
+
+ dsprintk(NDEBUG_QUEUES, instance, "complete_cmd: cmd %p\n", cmd);
+
+#ifdef SUPPORT_TAGS
+ cmd_free_tag(cmd);
+#else
+ hostdata->busy[scmd_id(cmd)] &= ~(1 << cmd->device->lun);
+#endif
+ cmd->scsi_done(cmd);
+}
+
+/**
* NCR5380_queue_command - queue a command
* @instance: the relevant SCSI adapter
* @cmd: SCSI command
@@ -1352,10 +1373,7 @@ static int NCR5380_select(struct Scsi_Ho
spin_lock_irq(&hostdata->lock);
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
cmd->result = DID_BAD_TARGET << 16;
-#ifdef SUPPORT_TAGS
- cmd_free_tag(cmd);
-#endif
- cmd->scsi_done(cmd);
+ complete_cmd(instance, cmd);
NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
dprintk(NDEBUG_SELECTION, "scsi%d: target did not respond within 250ms\n", HOSTNO);
return 0;
@@ -1866,7 +1884,7 @@ static void NCR5380_information_transfer
sink = 1;
do_abort(instance);
cmd->result = DID_ERROR << 16;
- cmd->scsi_done(cmd);
+ complete_cmd(instance, cmd);
return;
#endif
case PHASE_DATAIN:
@@ -1926,7 +1944,7 @@ static void NCR5380_information_transfer
sink = 1;
do_abort(instance);
cmd->result = DID_ERROR << 16;
- cmd->scsi_done(cmd);
+ complete_cmd(instance, cmd);
/* XXX - need to source or sink data here, as appropriate */
} else {
#ifdef REAL_DMA
@@ -1982,8 +2000,6 @@ static void NCR5380_information_transfer
if (ta->queue_size > ta->nr_allocated)
ta->queue_size = ta->nr_allocated;
}
-#else
- hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
#endif
/*
@@ -2021,8 +2037,13 @@ static void NCR5380_information_transfer
dsprintk(NDEBUG_AUTOSENSE | NDEBUG_QUEUES,
instance, "REQUEST SENSE cmd %p added to head of issue queue\n",
cmd);
+#ifdef SUPPORT_TAGS
+ cmd_free_tag(cmd);
+#else
+ hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
+#endif
} else {
- cmd->scsi_done(cmd);
+ complete_cmd(instance, cmd);
}
/*
@@ -2193,15 +2214,10 @@ static void NCR5380_information_transfer
hostdata->last_message = msgout;
NCR5380_transfer_pio(instance, &phase, &len, &data);
if (msgout == ABORT) {
-#ifdef SUPPORT_TAGS
- cmd_free_tag(cmd);
-#else
- hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
-#endif
hostdata->connected = NULL;
cmd->result = DID_ERROR << 16;
+ complete_cmd(instance, cmd);
maybe_release_dma_irq(instance);
- cmd->scsi_done(cmd);
NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
return;
}
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c 2016-01-03 16:04:20.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c 2016-01-03 16:04:24.000000000 +1100
@@ -726,6 +726,24 @@ static void NCR5380_exit(struct Scsi_Hos
}
/**
+ * complete_cmd - finish processing a command and return it to the SCSI ML
+ * @instance: the host instance
+ * @cmd: command to complete
+ */
+
+static void complete_cmd(struct Scsi_Host *instance,
+ struct scsi_cmnd *cmd)
+{
+ struct NCR5380_hostdata *hostdata = shost_priv(instance);
+
+ dsprintk(NDEBUG_QUEUES, instance, "complete_cmd: cmd %p\n", cmd);
+
+ hostdata->busy[scmd_id(cmd)] &= ~(1 << cmd->device->lun);
+
+ cmd->scsi_done(cmd);
+}
+
+/**
* NCR5380_queue_command - queue a command
* @instance: the relevant SCSI adapter
* @cmd: SCSI command
@@ -1171,7 +1189,7 @@ static int NCR5380_select(struct Scsi_Ho
spin_lock_irq(&hostdata->lock);
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
cmd->result = DID_BAD_TARGET << 16;
- cmd->scsi_done(cmd);
+ complete_cmd(instance, cmd);
NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
dprintk(NDEBUG_SELECTION, "scsi%d : target did not respond within 250ms\n",
instance->host_no);
@@ -1759,7 +1777,7 @@ static void NCR5380_information_transfer
sink = 1;
do_abort(instance);
cmd->result = DID_ERROR << 16;
- cmd->scsi_done(cmd);
+ complete_cmd(instance, cmd);
return;
#endif
case PHASE_DATAIN:
@@ -1804,7 +1822,7 @@ static void NCR5380_information_transfer
sink = 1;
do_abort(instance);
cmd->result = DID_ERROR << 16;
- cmd->scsi_done(cmd);
+ complete_cmd(instance, cmd);
/* XXX - need to source or sink data here, as appropriate */
} else
cmd->SCp.this_residual -= transfersize - len;
@@ -1834,7 +1852,6 @@ static void NCR5380_information_transfer
cmd, scmd_id(cmd), cmd->device->lun);
hostdata->connected = NULL;
- hostdata->busy[cmd->device->id] &= ~(1 << (cmd->device->lun & 0xFF));
/*
* I'm not sure what the correct thing to do here is :
@@ -1870,8 +1887,9 @@ static void NCR5380_information_transfer
dsprintk(NDEBUG_AUTOSENSE | NDEBUG_QUEUES,
instance, "REQUEST SENSE cmd %p added to head of issue queue\n",
cmd);
+ hostdata->busy[cmd->device->id] &= ~(1 << (cmd->device->lun & 0xFF));
} else {
- cmd->scsi_done(cmd);
+ complete_cmd(instance, cmd);
}
/*
@@ -2018,10 +2036,9 @@ static void NCR5380_information_transfer
hostdata->last_message = msgout;
NCR5380_transfer_pio(instance, &phase, &len, &data);
if (msgout == ABORT) {
- hostdata->busy[cmd->device->id] &= ~(1 << (cmd->device->lun & 0xFF));
hostdata->connected = NULL;
cmd->result = DID_ERROR << 16;
- cmd->scsi_done(cmd);
+ complete_cmd(instance, cmd);
NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
return;
}
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Finn Thain <fthain@telegraphics.com.au> |
|---|---|
| Date | 2016-01-03 06:30 +0100 |
| Subject | [PATCH v4 64/78] atari_NCR5380: Eliminate HOSTNO macro |
| Message-ID | <qMJoV-1cG-79@gated-at.bofh.it> |
| In reply to | #1300181 |
Keep the two core driver forks in sync.
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Tested-by: Ondrej Zary <linux@rainbow-software.org>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
---
drivers/scsi/NCR5380.c | 71 +++++++++++++++--------------
drivers/scsi/atari_NCR5380.c | 102 +++++++++++++++++++------------------------
2 files changed, 84 insertions(+), 89 deletions(-)
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c 2016-01-03 16:04:33.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c 2016-01-03 16:04:34.000000000 +1100
@@ -175,8 +175,6 @@
* possible) function may be used.
*/
-#define HOSTNO instance->host_no
-
static int do_abort(struct Scsi_Host *);
static void do_reset(struct Scsi_Host *);
@@ -1024,10 +1022,8 @@ static void NCR5380_main(struct work_str
&& !hostdata->dma_len
#endif
) {
- dprintk(NDEBUG_MAIN, "scsi%d: main: performing information transfer\n",
- HOSTNO);
+ dsprintk(NDEBUG_MAIN, instance, "main: performing information transfer\n");
NCR5380_information_transfer(instance);
- dprintk(NDEBUG_MAIN, "scsi%d: main: done set false\n", HOSTNO);
done = 0;
}
} while (!done);
@@ -1064,7 +1060,7 @@ static void NCR5380_dma_complete(struct
(BASR_PHASE_MATCH|BASR_ACK)) {
saved_data = NCR5380_read(INPUT_DATA_REG);
overrun = 1;
- dprintk(NDEBUG_DMA, "scsi%d: read overrun handled\n", HOSTNO);
+ dsprintk(NDEBUG_DMA, instance, "read overrun handled\n");
}
}
}
@@ -1169,8 +1165,8 @@ static irqreturn_t NCR5380_intr(int irq,
unsigned char mr = NCR5380_read(MODE_REG);
unsigned char sr = NCR5380_read(STATUS_REG);
- dprintk(NDEBUG_INTR, "scsi%d: IRQ %d, BASR 0x%02x, SR 0x%02x, MR 0x%02x\n",
- HOSTNO, irq, basr, sr, mr);
+ dsprintk(NDEBUG_INTR, instance, "IRQ %d, BASR 0x%02x, SR 0x%02x, MR 0x%02x\n",
+ irq, basr, sr, mr);
#if defined(REAL_DMA)
if ((mr & MR_DMA_MODE) || (mr & MR_MONITOR_BSY)) {
@@ -1179,7 +1175,7 @@ static irqreturn_t NCR5380_intr(int irq,
* for End of DMA errata need to happen in DMA Mode.
*/
- dprintk(NDEBUG_INTR, "scsi%d: interrupt in DMA mode\n", HOSTNO);
+ dsprintk(NDEBUG_INTR, instance, "interrupt in DMA mode\n");
if (hostdata->connected) {
NCR5380_dma_complete(instance);
@@ -1196,8 +1192,7 @@ static irqreturn_t NCR5380_intr(int irq,
NCR5380_write(SELECT_ENABLE_REG, 0);
NCR5380_read(RESET_PARITY_INTERRUPT_REG);
- dprintk(NDEBUG_INTR, "scsi%d: interrupt with SEL and IO\n",
- HOSTNO);
+ dsprintk(NDEBUG_INTR, instance, "interrupt with SEL and IO\n");
if (!hostdata->connected) {
NCR5380_reselect(instance);
@@ -1209,7 +1204,7 @@ static irqreturn_t NCR5380_intr(int irq,
/* Probably Bus Reset */
NCR5380_read(RESET_PARITY_INTERRUPT_REG);
- dprintk(NDEBUG_INTR, "scsi%d: unknown interrupt\n", HOSTNO);
+ dsprintk(NDEBUG_INTR, instance, "unknown interrupt\n");
#ifdef SUN3_SCSI_VME
dregs->csr |= CSR_DMA_ENABLE;
#endif
@@ -1266,8 +1261,8 @@ static struct scsi_cmnd *NCR5380_select(
int err;
NCR5380_dprint(NDEBUG_ARBITRATION, instance);
- dprintk(NDEBUG_ARBITRATION, "scsi%d: starting arbitration, id = %d\n", HOSTNO,
- instance->this_id);
+ dsprintk(NDEBUG_ARBITRATION, instance, "starting arbitration, id = %d\n",
+ instance->this_id);
/*
* Arbitration and selection phases are slow and involve dropping the
@@ -1321,8 +1316,7 @@ static struct scsi_cmnd *NCR5380_select(
(NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_higher_mask) ||
(NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST)) {
NCR5380_write(MODE_REG, MR_BASE);
- dprintk(NDEBUG_ARBITRATION, "scsi%d: lost arbitration, deasserting MR_ARBITRATE\n",
- HOSTNO);
+ dsprintk(NDEBUG_ARBITRATION, instance, "lost arbitration, deasserting MR_ARBITRATE\n");
spin_lock_irq(&hostdata->lock);
goto out;
}
@@ -1356,7 +1350,7 @@ static struct scsi_cmnd *NCR5380_select(
goto out;
}
- dprintk(NDEBUG_ARBITRATION, "scsi%d: won arbitration\n", HOSTNO);
+ dsprintk(NDEBUG_ARBITRATION, instance, "won arbitration\n");
/*
* Now that we have won arbitration, start Selection process, asserting
@@ -1412,7 +1406,7 @@ static struct scsi_cmnd *NCR5380_select(
udelay(1);
- dprintk(NDEBUG_SELECTION, "scsi%d: selecting target %d\n", HOSTNO, cmd->device->id);
+ dsprintk(NDEBUG_SELECTION, instance, "selecting target %d\n", scmd_id(cmd));
/*
* The SCSI specification calls for a 250 ms timeout for the actual
@@ -1486,8 +1480,8 @@ static struct scsi_cmnd *NCR5380_select(
goto out;
}
- dprintk(NDEBUG_SELECTION, "scsi%d: target %d selected, going into MESSAGE OUT phase.\n",
- HOSTNO, cmd->device->id);
+ dsprintk(NDEBUG_SELECTION, instance, "target %d selected, going into MESSAGE OUT phase.\n",
+ scmd_id(cmd));
tmp[0] = IDENTIFY(1, cmd->device->lun);
#ifdef SUPPORT_TAGS
@@ -1506,7 +1500,7 @@ static struct scsi_cmnd *NCR5380_select(
data = tmp;
phase = PHASE_MSGOUT;
NCR5380_transfer_pio(instance, &phase, &len, &data);
- dprintk(NDEBUG_SELECTION, "scsi%d: nexus established.\n", HOSTNO);
+ dsprintk(NDEBUG_SELECTION, instance, "nexus established.\n");
/* XXX need to handle errors here */
hostdata->connected = cmd;
@@ -1578,11 +1572,11 @@ static int NCR5380_transfer_pio(struct S
if (NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ) < 0)
break;
- dprintk(NDEBUG_HANDSHAKE, "scsi%d: REQ detected\n", HOSTNO);
+ dsprintk(NDEBUG_HANDSHAKE, instance, "REQ asserted\n");
/* Check for phase mismatch */
if ((NCR5380_read(STATUS_REG) & PHASE_MASK) != p) {
- dprintk(NDEBUG_PIO, "scsi%d: phase mismatch\n", HOSTNO);
+ dsprintk(NDEBUG_PIO, instance, "phase mismatch\n");
NCR5380_dprint_phase(NDEBUG_PIO, instance);
break;
}
@@ -1624,7 +1618,7 @@ static int NCR5380_transfer_pio(struct S
STATUS_REG, SR_REQ, 0, 5 * HZ) < 0)
break;
- dprintk(NDEBUG_HANDSHAKE, "scsi%d: req false, handshake complete\n", HOSTNO);
+ dsprintk(NDEBUG_HANDSHAKE, instance, "REQ negated, handshake complete\n");
/*
* We have several special cases to consider during REQ/ACK handshaking :
@@ -1645,7 +1639,7 @@ static int NCR5380_transfer_pio(struct S
}
} while (--c);
- dprintk(NDEBUG_PIO, "scsi%d: residual %d\n", HOSTNO, c);
+ dsprintk(NDEBUG_PIO, instance, "residual %d\n", c);
*count = c;
*data = d;
@@ -1791,9 +1785,8 @@ static int NCR5380_transfer_dma(struct S
}
hostdata->dma_len = c;
- dprintk(NDEBUG_DMA, "scsi%d: initializing DMA for %s, %d bytes %s %p\n",
- instance->host_no, (p & SR_IO) ? "reading" : "writing",
- c, (p & SR_IO) ? "to" : "from", *data);
+ dsprintk(NDEBUG_DMA, instance, "initializing DMA %s: length %d, address %p\n",
+ (p & SR_IO) ? "receive" : "send", c, *data);
/* netbsd turns off ints here, why not be safe and do it too */
@@ -1829,9 +1822,8 @@ static int NCR5380_transfer_dma(struct S
if (hostdata->read_overruns && (p & SR_IO))
c -= hostdata->read_overruns;
- dprintk(NDEBUG_DMA, "scsi%d: initializing DMA for %s, %d bytes %s %p\n",
- HOSTNO, (p & SR_IO) ? "reading" : "writing",
- c, (p & SR_IO) ? "to" : "from", d);
+ dsprintk(NDEBUG_DMA, instance, "initializing DMA %s: length %d, address %p\n",
+ (p & SR_IO) ? "receive" : "send", c, d);
NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p));
NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_MONITOR_BSY |
@@ -1978,9 +1970,9 @@ static void NCR5380_information_transfer
* they are at contiguous physical addresses.
*/
merge_contiguous_buffers(cmd);
- dprintk(NDEBUG_INFORMATION, "scsi%d: %d bytes and %d buffers left\n",
- HOSTNO, cmd->SCp.this_residual,
- cmd->SCp.buffers_residual);
+ dsprintk(NDEBUG_INFORMATION, instance, "%d bytes and %d buffers left\n",
+ cmd->SCp.this_residual,
+ cmd->SCp.buffers_residual);
}
/*
@@ -2068,11 +2060,12 @@ static void NCR5380_information_transfer
#ifdef SUPPORT_TAGS
cmd_free_tag(cmd);
if (status_byte(cmd->SCp.Status) == QUEUE_FULL) {
- struct tag_alloc *ta = &hostdata->TagAlloc[scmd_id(cmd)][cmd->device->lun];
- dprintk(NDEBUG_TAGS, "scsi%d: target %d lun %llu returned "
- "QUEUE_FULL after %d commands\n",
- HOSTNO, cmd->device->id, cmd->device->lun,
- ta->nr_allocated);
+ u8 lun = cmd->device->lun;
+ struct tag_alloc *ta = &hostdata->TagAlloc[scmd_id(cmd)][lun];
+
+ dsprintk(NDEBUG_TAGS, instance,
+ "QUEUE_FULL %p target %d lun %d nr_allocated %d\n",
+ cmd, scmd_id(cmd), lun, ta->nr_allocated);
if (ta->queue_size > ta->nr_allocated)
ta->queue_size = ta->nr_allocated;
}
@@ -2126,10 +2119,8 @@ static void NCR5380_information_transfer
cmd->device->tagged_supported = 0;
hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);
cmd->tag = TAG_NONE;
- dprintk(NDEBUG_TAGS, "scsi%d: target %d lun %llu rejected "
- "QUEUE_TAG message; tagged queuing "
- "disabled\n",
- HOSTNO, cmd->device->id, cmd->device->lun);
+ dsprintk(NDEBUG_TAGS, instance, "target %d lun %llu rejected QUEUE_TAG message; tagged queuing disabled\n",
+ scmd_id(cmd), cmd->device->lun);
break;
}
break;
@@ -2188,14 +2179,15 @@ static void NCR5380_information_transfer
spin_unlock_irq(&hostdata->lock);
- dprintk(NDEBUG_EXTENDED, "scsi%d: receiving extended message\n", HOSTNO);
+ dsprintk(NDEBUG_EXTENDED, instance, "receiving extended message\n");
len = 2;
data = extended_msg + 1;
phase = PHASE_MSGIN;
NCR5380_transfer_pio(instance, &phase, &len, &data);
- dprintk(NDEBUG_EXTENDED, "scsi%d: length=%d, code=0x%02x\n", HOSTNO,
- (int)extended_msg[1], (int)extended_msg[2]);
+ dsprintk(NDEBUG_EXTENDED, instance, "length %d, code 0x%02x\n",
+ (int)extended_msg[1],
+ (int)extended_msg[2]);
if (!len && extended_msg[1] > 0 &&
extended_msg[1] <= sizeof(extended_msg) - 2) {
@@ -2206,8 +2198,8 @@ static void NCR5380_information_transfer
phase = PHASE_MSGIN;
NCR5380_transfer_pio(instance, &phase, &len, &data);
- dprintk(NDEBUG_EXTENDED, "scsi%d: message received, residual %d\n",
- HOSTNO, len);
+ dsprintk(NDEBUG_EXTENDED, instance, "message received, residual %d\n",
+ len);
switch (extended_msg[2]) {
case EXTENDED_SDTR:
@@ -2335,7 +2327,7 @@ static void NCR5380_reselect(struct Scsi
target_mask = NCR5380_read(CURRENT_SCSI_DATA_REG) & ~(hostdata->id_mask);
- dprintk(NDEBUG_RESELECTION, "scsi%d: reselect\n", HOSTNO);
+ dsprintk(NDEBUG_RESELECTION, instance, "reselect\n");
/*
* At this point, we have detected that our SCSI ID is on the bus,
@@ -2405,8 +2397,8 @@ static void NCR5380_reselect(struct Scsi
if (!NCR5380_transfer_pio(instance, &phase, &len, &data) &&
msg[1] == SIMPLE_QUEUE_TAG)
tag = msg[2];
- dprintk(NDEBUG_TAGS, "scsi%d: target mask %02x, lun %d sent tag %d at "
- "reselection\n", HOSTNO, target_mask, lun, tag);
+ dsprintk(NDEBUG_TAGS, instance, "reselect: target mask %02x, lun %d sent tag %d\n",
+ target_mask, lun, tag);
}
#endif
@@ -2491,14 +2483,14 @@ static void NCR5380_reselect(struct Scsi
if (!NCR5380_transfer_pio(instance, &phase, &len, &data) &&
msg[1] == SIMPLE_QUEUE_TAG)
tag = msg[2];
- dprintk(NDEBUG_TAGS, "scsi%d: target mask %02x, lun %d sent tag %d at reselection\n"
- HOSTNO, target_mask, lun, tag);
+ dsprintk(NDEBUG_TAGS, instance, "reselect: target mask %02x, lun %d sent tag %d\n"
+ target_mask, lun, tag);
}
#endif
hostdata->connected = tmp;
- dprintk(NDEBUG_RESELECTION, "scsi%d: nexus established, target = %d, lun = %llu, tag = %d\n",
- HOSTNO, tmp->device->id, tmp->device->lun, tmp->tag);
+ dsprintk(NDEBUG_RESELECTION, instance, "nexus established, target %d, lun %llu, tag %d\n",
+ scmd_id(tmp), tmp->device->lun, tmp->tag);
}
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c 2016-01-03 16:04:33.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c 2016-01-03 16:04:34.000000000 +1100
@@ -926,9 +926,8 @@ static void NCR5380_main(struct work_str
&& !hostdata->dmalen
#endif
) {
- dprintk(NDEBUG_MAIN, "scsi%d : main() : performing information transfer\n", instance->host_no);
+ dsprintk(NDEBUG_MAIN, instance, "main: performing information transfer\n");
NCR5380_information_transfer(instance);
- dprintk(NDEBUG_MAIN, "scsi%d : main() : done set false\n", instance->host_no);
done = 0;
}
} while (!done);
@@ -986,8 +985,8 @@ static irqreturn_t NCR5380_intr(int irq,
unsigned char mr = NCR5380_read(MODE_REG);
unsigned char sr = NCR5380_read(STATUS_REG);
- dprintk(NDEBUG_INTR, "scsi%d: IRQ %d, BASR 0x%02x, SR 0x%02x, MR 0x%02x\n",
- instance->host_no, irq, basr, sr, mr);
+ dsprintk(NDEBUG_INTR, instance, "IRQ %d, BASR 0x%02x, SR 0x%02x, MR 0x%02x\n",
+ irq, basr, sr, mr);
#if defined(REAL_DMA)
if ((mr & MR_DMA_MODE) || (mr & MR_MONITOR_BSY)) {
@@ -996,7 +995,7 @@ static irqreturn_t NCR5380_intr(int irq,
* for End of DMA errata need to happen in DMA Mode.
*/
- dprintk(NDEBUG_INTR, "scsi%d: interrupt in DMA mode\n", intance->host_no);
+ dsprintk(NDEBUG_INTR, instance, "interrupt in DMA mode\n");
int transferred;
@@ -1023,8 +1022,7 @@ static irqreturn_t NCR5380_intr(int irq,
NCR5380_write(SELECT_ENABLE_REG, 0);
NCR5380_read(RESET_PARITY_INTERRUPT_REG);
- dprintk(NDEBUG_INTR, "scsi%d: interrupt with SEL and IO\n",
- instance->host_no);
+ dsprintk(NDEBUG_INTR, instance, "interrupt with SEL and IO\n");
if (!hostdata->connected) {
NCR5380_reselect(instance);
@@ -1036,7 +1034,7 @@ static irqreturn_t NCR5380_intr(int irq,
/* Probably Bus Reset */
NCR5380_read(RESET_PARITY_INTERRUPT_REG);
- dprintk(NDEBUG_INTR, "scsi%d: unknown interrupt\n", instance->host_no);
+ dsprintk(NDEBUG_INTR, instance, "unknown interrupt\n");
}
handled = 1;
} else {
@@ -1091,7 +1089,8 @@ static struct scsi_cmnd *NCR5380_select(
int err;
NCR5380_dprint(NDEBUG_ARBITRATION, instance);
- dprintk(NDEBUG_ARBITRATION, "scsi%d : starting arbitration, id = %d\n", instance->host_no, instance->this_id);
+ dsprintk(NDEBUG_ARBITRATION, instance, "starting arbitration, id = %d\n",
+ instance->this_id);
/*
* Arbitration and selection phases are slow and involve dropping the
@@ -1143,7 +1142,7 @@ static struct scsi_cmnd *NCR5380_select(
/* Check for lost arbitration */
if ((NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) || (NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_higher_mask) || (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST)) {
NCR5380_write(MODE_REG, MR_BASE);
- dprintk(NDEBUG_ARBITRATION, "scsi%d : lost arbitration, deasserting MR_ARBITRATE\n", instance->host_no);
+ dsprintk(NDEBUG_ARBITRATION, instance, "lost arbitration, deasserting MR_ARBITRATE\n");
spin_lock_irq(&hostdata->lock);
goto out;
}
@@ -1177,7 +1176,7 @@ static struct scsi_cmnd *NCR5380_select(
goto out;
}
- dprintk(NDEBUG_ARBITRATION, "scsi%d : won arbitration\n", instance->host_no);
+ dsprintk(NDEBUG_ARBITRATION, instance, "won arbitration\n");
/*
* Now that we have won arbitration, start Selection process, asserting
@@ -1231,7 +1230,7 @@ static struct scsi_cmnd *NCR5380_select(
udelay(1);
- dprintk(NDEBUG_SELECTION, "scsi%d : selecting target %d\n", instance->host_no, scmd_id(cmd));
+ dsprintk(NDEBUG_SELECTION, instance, "selecting target %d\n", scmd_id(cmd));
/*
* The SCSI specification calls for a 250 ms timeout for the actual
@@ -1305,7 +1304,8 @@ static struct scsi_cmnd *NCR5380_select(
goto out;
}
- dprintk(NDEBUG_SELECTION, "scsi%d : target %d selected, going into MESSAGE OUT phase.\n", instance->host_no, cmd->device->id);
+ dsprintk(NDEBUG_SELECTION, instance, "target %d selected, going into MESSAGE OUT phase.\n",
+ scmd_id(cmd));
tmp[0] = IDENTIFY(((instance->irq == NO_IRQ) ? 0 : 1), cmd->device->lun);
len = 1;
@@ -1315,7 +1315,7 @@ static struct scsi_cmnd *NCR5380_select(
data = tmp;
phase = PHASE_MSGOUT;
NCR5380_transfer_pio(instance, &phase, &len, &data);
- dprintk(NDEBUG_SELECTION, "scsi%d : nexus established.\n", instance->host_no);
+ dsprintk(NDEBUG_SELECTION, instance, "nexus established.\n");
/* XXX need to handle errors here */
hostdata->connected = cmd;
@@ -1362,11 +1362,6 @@ static int NCR5380_transfer_pio(struct S
int c = *count;
unsigned char *d = *data;
- if (!(p & SR_IO))
- dprintk(NDEBUG_PIO, "scsi%d : pio write %d bytes\n", instance->host_no, c);
- else
- dprintk(NDEBUG_PIO, "scsi%d : pio read %d bytes\n", instance->host_no, c);
-
/*
* The NCR5380 chip will only drive the SCSI bus when the
* phase specified in the appropriate bits of the TARGET COMMAND
@@ -1384,12 +1379,12 @@ static int NCR5380_transfer_pio(struct S
if (NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ) < 0)
break;
- dprintk(NDEBUG_HANDSHAKE, "scsi%d : REQ detected\n", instance->host_no);
+ dsprintk(NDEBUG_HANDSHAKE, instance, "REQ asserted\n");
/* Check for phase mismatch */
if ((NCR5380_read(STATUS_REG) & PHASE_MASK) != p) {
- dprintk(NDEBUG_HANDSHAKE, "scsi%d : phase mismatch\n", instance->host_no);
- NCR5380_dprint_phase(NDEBUG_HANDSHAKE, instance);
+ dsprintk(NDEBUG_PIO, instance, "phase mismatch\n");
+ NCR5380_dprint_phase(NDEBUG_PIO, instance);
break;
}
/* Do actual transfer from SCSI bus to / from memory */
@@ -1426,7 +1421,7 @@ static int NCR5380_transfer_pio(struct S
STATUS_REG, SR_REQ, 0, 5 * HZ) < 0)
break;
- dprintk(NDEBUG_HANDSHAKE, "scsi%d : req false, handshake complete\n", instance->host_no);
+ dsprintk(NDEBUG_HANDSHAKE, instance, "REQ negated, handshake complete\n");
/*
* We have several special cases to consider during REQ/ACK handshaking :
@@ -1447,7 +1442,7 @@ static int NCR5380_transfer_pio(struct S
}
} while (--c);
- dprintk(NDEBUG_PIO, "scsi%d : residual %d\n", instance->host_no, c);
+ dsprintk(NDEBUG_PIO, instance, "residual %d\n", c);
*count = c;
*data = d;
@@ -1597,8 +1592,10 @@ static int NCR5380_transfer_dma(struct S
if (!(hostdata->flags & FLAG_NO_DMA_FIXUPS))
c -= 2;
}
- dprintk(NDEBUG_DMA, "scsi%d : initializing DMA channel %d for %s, %d bytes %s %0x\n", instance->host_no, instance->dma_channel, (p & SR_IO) ? "reading" : "writing", c, (p & SR_IO) ? "to" : "from", (unsigned) d);
hostdata->dma_len = (p & SR_IO) ? NCR5380_dma_read_setup(instance, d, c) : NCR5380_dma_write_setup(instance, d, c);
+
+ dsprintk(NDEBUG_DMA, instance, "initializing DMA %s: length %d, address %p\n",
+ (p & SR_IO) ? "receive" : "send", c, *data);
#endif
NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p));
@@ -1700,7 +1697,8 @@ static int NCR5380_transfer_dma(struct S
}
}
- dprintk(NDEBUG_DMA, "scsi%d : polled DMA transfer complete, basr 0x%X, sr 0x%X\n", instance->host_no, tmp, NCR5380_read(STATUS_REG));
+ dsprintk(NDEBUG_DMA, "polled DMA transfer complete, basr 0x%02x, sr 0x%02x\n",
+ tmp, NCR5380_read(STATUS_REG));
NCR5380_write(MODE_REG, MR_BASE);
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
@@ -1870,7 +1868,9 @@ static void NCR5380_information_transfer
--cmd->SCp.buffers_residual;
cmd->SCp.this_residual = cmd->SCp.buffer->length;
cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
- dprintk(NDEBUG_INFORMATION, "scsi%d : %d bytes and %d buffers left\n", instance->host_no, cmd->SCp.this_residual, cmd->SCp.buffers_residual);
+ dsprintk(NDEBUG_INFORMATION, instance, "%d bytes and %d buffers left\n",
+ cmd->SCp.this_residual,
+ cmd->SCp.buffers_residual);
}
/*
* The preferred transfer method is going to be
@@ -2025,14 +2025,15 @@ static void NCR5380_information_transfer
spin_unlock_irq(&hostdata->lock);
- dprintk(NDEBUG_EXTENDED, "scsi%d : receiving extended message\n", instance->host_no);
+ dsprintk(NDEBUG_EXTENDED, instance, "receiving extended message\n");
len = 2;
data = extended_msg + 1;
phase = PHASE_MSGIN;
NCR5380_transfer_pio(instance, &phase, &len, &data);
-
- dprintk(NDEBUG_EXTENDED, "scsi%d : length=%d, code=0x%02x\n", instance->host_no, (int) extended_msg[1], (int) extended_msg[2]);
+ dsprintk(NDEBUG_EXTENDED, instance, "length %d, code 0x%02x\n",
+ (int)extended_msg[1],
+ (int)extended_msg[2]);
if (!len && extended_msg[1] > 0 &&
extended_msg[1] <= sizeof(extended_msg) - 2) {
@@ -2043,7 +2044,8 @@ static void NCR5380_information_transfer
phase = PHASE_MSGIN;
NCR5380_transfer_pio(instance, &phase, &len, &data);
- dprintk(NDEBUG_EXTENDED, "scsi%d : message received, residual %d\n", instance->host_no, len);
+ dsprintk(NDEBUG_EXTENDED, instance, "message received, residual %d\n",
+ len);
switch (extended_msg[2]) {
case EXTENDED_SDTR:
@@ -2160,7 +2162,8 @@ static void NCR5380_reselect(struct Scsi
NCR5380_write(MODE_REG, MR_BASE);
target_mask = NCR5380_read(CURRENT_SCSI_DATA_REG) & ~(hostdata->id_mask);
- dprintk(NDEBUG_RESELECTION, "scsi%d : reselect\n", instance->host_no);
+
+ dsprintk(NDEBUG_RESELECTION, instance, "reselect\n");
/*
* At this point, we have detected that our SCSI ID is on the bus,
@@ -2249,8 +2252,8 @@ static void NCR5380_reselect(struct Scsi
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
hostdata->connected = tmp;
- dprintk(NDEBUG_RESELECTION, "scsi%d : nexus established, target = %d, lun = %llu, tag = %d\n",
- instance->host_no, tmp->device->id, tmp->device->lun, tmp->tag);
+ dsprintk(NDEBUG_RESELECTION, instance, "nexus established, target %d, lun %llu, tag %d\n",
+ scmd_id(tmp), tmp->device->lun, tmp->tag);
}
/*
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Finn Thain <fthain@telegraphics.com.au> |
|---|---|
| Date | 2016-01-03 06:30 +0100 |
| Subject | [PATCH v4 78/78] ncr5380: Add support for HP C2502 |
| Message-ID | <qMJoV-1cG-81@gated-at.bofh.it> |
| In reply to | #1300181 |
From: Ondrej Zary <linux@rainbow-software.org>
HP C2502 cards (based on 53C400A chips) use different magic numbers for
software-based I/O address configuration than other cards.
The configuration is also extended to allow setting the IRQ.
Move the configuration to a new function magic_configure() and move
magic the magic numbers into an array. Add new magic numbers for these
HP cards and hp_c2502 module parameter to use them, e.g.:
modprobe g_NCR5380 ncr_irq=7 ncr_addr=0x280 hp_c2502=1
Tested with HP C2502 and DTCT-436P.
Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
---
Changes to Ondrej's versions:
- Omit a redundant comment.
- Throw an error if MMIO register locations are not known.
- Avoid 'if (...) { ... continue; } else { ... }'
- Fix "warning: 'port_idx' may be used uninitialized" and
"warning: 'magic' may be used uninitialized" for port-mapped config.
- Rebased.
---
drivers/scsi/g_NCR5380.c | 74 ++++++++++++++++++++++++++++++++++++-----------
drivers/scsi/g_NCR5380.h | 1
2 files changed, 59 insertions(+), 16 deletions(-)
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c 2016-01-03 16:04:55.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c 2016-01-03 16:04:56.000000000 +1100
@@ -80,6 +80,7 @@ static int ncr_5380;
static int ncr_53c400;
static int ncr_53c400a;
static int dtc_3181e;
+static int hp_c2502;
static struct override {
NCR5380_map_type NCR5380_map_name;
@@ -225,6 +226,30 @@ static int __init do_DTC3181E_setup(char
#endif
+#ifndef SCSI_G_NCR5380_MEM
+/*
+ * Configure I/O address of 53C400A or DTC436 by writing magic numbers
+ * to ports 0x779 and 0x379.
+ */
+static void magic_configure(int idx, u8 irq, u8 magic[])
+{
+ u8 cfg = 0;
+
+ outb(magic[0], 0x779);
+ outb(magic[1], 0x379);
+ outb(magic[2], 0x379);
+ 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 (idx >= 0 && idx <= 7)
+ cfg = 0x80 | idx | (irq << 4);
+ outb(cfg, 0x379);
+}
+#endif
+
/**
* generic_NCR5380_detect - look for NCR5380 controllers
* @tpnt: the scsi template
@@ -241,8 +266,10 @@ static int __init generic_NCR5380_detect
static int current_override;
int count;
unsigned int *ports;
+ u8 *magic = NULL;
#ifndef SCSI_G_NCR5380_MEM
int i;
+ int port_idx = -1;
unsigned long region_size = 16;
#endif
static unsigned int __initdata ncr_53c400a_ports[] = {
@@ -251,6 +278,12 @@ static int __init generic_NCR5380_detect
static unsigned int __initdata dtc_3181e_ports[] = {
0x220, 0x240, 0x280, 0x2a0, 0x2c0, 0x300, 0x320, 0x340, 0
};
+ static u8 ncr_53c400a_magic[] __initdata = { /* 53C400A & DTC436 */
+ 0x59, 0xb9, 0xc5, 0xae, 0xa6
+ };
+ static u8 hp_c2502_magic[] __initdata = { /* HP C2502 */
+ 0x0f, 0x22, 0xf0, 0x20, 0x80
+ };
int flags;
struct Scsi_Host *instance;
struct NCR5380_hostdata *hostdata;
@@ -273,6 +306,8 @@ static int __init generic_NCR5380_detect
overrides[0].board = BOARD_NCR53C400A;
else if (dtc_3181e)
overrides[0].board = BOARD_DTC3181E;
+ else if (hp_c2502)
+ overrides[0].board = BOARD_HP_C2502;
#ifndef SCSI_G_NCR5380_MEM
if (!current_override && isapnp_present()) {
struct pnp_dev *dev = NULL;
@@ -325,24 +360,26 @@ static int __init generic_NCR5380_detect
case BOARD_NCR53C400A:
flags = FLAG_NO_DMA_FIXUP;
ports = ncr_53c400a_ports;
+ magic = ncr_53c400a_magic;
+ break;
+ case BOARD_HP_C2502:
+ flags = FLAG_NO_DMA_FIXUP;
+ ports = ncr_53c400a_ports;
+ magic = hp_c2502_magic;
break;
case BOARD_DTC3181E:
flags = FLAG_NO_DMA_FIXUP;
ports = dtc_3181e_ports;
+ magic = ncr_53c400a_magic;
break;
}
#ifndef SCSI_G_NCR5380_MEM
- if (ports) {
+ if (ports && magic) {
/* wakeup sequence for the NCR53C400A and DTC3181E */
/* Disable the adapter and look for a free io port */
- outb(0x59, 0x779);
- outb(0xb9, 0x379);
- outb(0xc5, 0x379);
- outb(0xae, 0x379);
- outb(0xa6, 0x379);
- outb(0x00, 0x379);
+ magic_configure(-1, 0, magic);
if (overrides[current_override].NCR5380_map_name != PORT_AUTO)
for (i = 0; ports[i]; i++) {
@@ -361,17 +398,12 @@ static int __init generic_NCR5380_detect
}
if (ports[i]) {
/* At this point we have our region reserved */
- outb(0x59, 0x779);
- outb(0xb9, 0x379);
- outb(0xc5, 0x379);
- outb(0xae, 0x379);
- outb(0xa6, 0x379);
- outb(0x80 | i, 0x379); /* set io port to be used */
+ magic_configure(i, 0, magic); /* no IRQ yet */
outb(0xc0, ports[i] + 9);
if (inb(ports[i] + 9) != 0x80)
continue;
- else
- overrides[current_override].NCR5380_map_name = ports[i];
+ overrides[current_override].NCR5380_map_name = ports[i];
+ port_idx = i;
} else
continue;
}
@@ -417,6 +449,7 @@ static int __init generic_NCR5380_detect
hostdata->io_width = 2; /* 16-bit PDMA */
/* fall through */
case BOARD_NCR53C400A:
+ case BOARD_HP_C2502:
hostdata->c400_ctl_status = 9;
hostdata->c400_blk_cnt = 10;
hostdata->c400_host_buf = 8;
@@ -433,6 +466,7 @@ static int __init generic_NCR5380_detect
break;
case BOARD_DTC3181E:
case BOARD_NCR53C400A:
+ case BOARD_HP_C2502:
pr_err(DRV_MODULE_NAME ": unknown register offsets\n");
goto out_unregister;
}
@@ -445,6 +479,7 @@ static int __init generic_NCR5380_detect
case BOARD_NCR53C400:
case BOARD_DTC3181E:
case BOARD_NCR53C400A:
+ case BOARD_HP_C2502:
NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
}
@@ -459,12 +494,18 @@ static int __init generic_NCR5380_detect
if (instance->irq == 255)
instance->irq = NO_IRQ;
- if (instance->irq != NO_IRQ)
+ if (instance->irq != NO_IRQ) {
+#ifndef SCSI_G_NCR5380_MEM
+ /* set IRQ for HP C2502 */
+ if (overrides[current_override].board == BOARD_HP_C2502)
+ magic_configure(port_idx, instance->irq, magic);
+#endif
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;
}
+ }
if (instance->irq == NO_IRQ) {
printk(KERN_INFO "scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no);
@@ -751,6 +792,7 @@ module_param(ncr_5380, int, 0);
module_param(ncr_53c400, int, 0);
module_param(ncr_53c400a, int, 0);
module_param(dtc_3181e, int, 0);
+module_param(hp_c2502, int, 0);
MODULE_LICENSE("GPL");
#if !defined(SCSI_G_NCR5380_MEM) && defined(MODULE)
Index: linux/drivers/scsi/g_NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.h 2016-01-03 16:04:54.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.h 2016-01-03 16:04:56.000000000 +1100
@@ -88,6 +88,7 @@
#define BOARD_NCR53C400 1
#define BOARD_NCR53C400A 2
#define BOARD_DTC3181E 3
+#define BOARD_HP_C2502 4
#endif /* GENERIC_NCR5380_H */
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Finn Thain <fthain@telegraphics.com.au> |
|---|---|
| Date | 2016-01-03 06:30 +0100 |
| Subject | [PATCH v4 72/78] ncr5380: Cleanup whitespace and parentheses |
| Message-ID | <qMJoV-1cG-85@gated-at.bofh.it> |
| In reply to | #1300181 |
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Tested-by: Ondrej Zary <linux@rainbow-software.org>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
---
drivers/scsi/NCR5380.c | 30 +++++++++++++++++++-----------
drivers/scsi/atari_NCR5380.c | 26 +++++++++++++-------------
2 files changed, 32 insertions(+), 24 deletions(-)
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c 2016-01-03 16:04:46.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c 2016-01-03 16:04:49.000000000 +1100
@@ -1113,7 +1113,7 @@ static struct scsi_cmnd *NCR5380_select(
* the host and target ID's on the SCSI bus.
*/
- NCR5380_write(OUTPUT_DATA_REG, (hostdata->id_mask | (1 << scmd_id(cmd))));
+ NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask | (1 << scmd_id(cmd)));
/*
* Raise ATN while SEL is true before BSY goes false from arbitration,
@@ -1121,7 +1121,8 @@ static struct scsi_cmnd *NCR5380_select(
* phase immediately after selection.
*/
- NCR5380_write(INITIATOR_COMMAND_REG, (ICR_BASE | ICR_ASSERT_BSY | ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_SEL));
+ NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_BSY |
+ ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_SEL);
NCR5380_write(MODE_REG, MR_BASE);
/*
@@ -1139,7 +1140,8 @@ static struct scsi_cmnd *NCR5380_select(
udelay(1); /* wingel -- wait two bus deskew delay >2*45ns */
/* Reset BSY */
- NCR5380_write(INITIATOR_COMMAND_REG, (ICR_BASE | ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_SEL));
+ NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA |
+ ICR_ASSERT_ATN | ICR_ASSERT_SEL);
/*
* Something weird happens when we cease to drive BSY - looks
@@ -1249,7 +1251,7 @@ static struct scsi_cmnd *NCR5380_select(
/* XXX need to handle errors here */
hostdata->connected = cmd;
- hostdata->busy[cmd->device->id] |= (1 << (cmd->device->lun & 0xFF));
+ hostdata->busy[cmd->device->id] |= 1 << cmd->device->lun;
initialize_SCp(cmd);
@@ -1340,11 +1342,14 @@ static int NCR5380_transfer_pio(struct S
if (!((p & SR_MSG) && c > 1)) {
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA);
NCR5380_dprint(NDEBUG_PIO, instance);
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA | ICR_ASSERT_ACK);
+ NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
+ ICR_ASSERT_DATA | ICR_ASSERT_ACK);
} else {
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA | ICR_ASSERT_ATN);
+ NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
+ ICR_ASSERT_DATA | ICR_ASSERT_ATN);
NCR5380_dprint(NDEBUG_PIO, instance);
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_ACK);
+ NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
+ ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_ACK);
}
} else {
NCR5380_dprint(NDEBUG_PIO, instance);
@@ -1775,10 +1780,12 @@ static void NCR5380_information_transfer
if (sink && (phase != PHASE_MSGOUT)) {
NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp));
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN | ICR_ASSERT_ACK);
+ NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN |
+ ICR_ASSERT_ACK);
while (NCR5380_read(STATUS_REG) & SR_REQ)
;
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
+ NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
+ ICR_ASSERT_ATN);
sink = 0;
continue;
}
@@ -1848,8 +1855,9 @@ static void NCR5380_information_transfer
#endif /* defined(PSEUDO_DMA) || defined(REAL_DMA_POLL) */
{
spin_unlock_irq(&hostdata->lock);
- NCR5380_transfer_pio(instance, &phase, (int *) &cmd->SCp.this_residual, (unsigned char **)
- &cmd->SCp.ptr);
+ NCR5380_transfer_pio(instance, &phase,
+ (int *)&cmd->SCp.this_residual,
+ (unsigned char **)&cmd->SCp.ptr);
spin_lock_irq(&hostdata->lock);
}
break;
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c 2016-01-03 16:04:48.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c 2016-01-03 16:04:49.000000000 +1100
@@ -1314,7 +1314,7 @@ static struct scsi_cmnd *NCR5380_select(
* the host and target ID's on the SCSI bus.
*/
- NCR5380_write(OUTPUT_DATA_REG, (hostdata->id_mask | (1 << cmd->device->id)));
+ NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask | (1 << scmd_id(cmd)));
/*
* Raise ATN while SEL is true before BSY goes false from arbitration,
@@ -1322,8 +1322,8 @@ static struct scsi_cmnd *NCR5380_select(
* phase immediately after selection.
*/
- NCR5380_write(INITIATOR_COMMAND_REG, (ICR_BASE | ICR_ASSERT_BSY |
- ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_SEL ));
+ NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_BSY |
+ ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_SEL);
NCR5380_write(MODE_REG, MR_BASE);
/*
@@ -1341,8 +1341,8 @@ static struct scsi_cmnd *NCR5380_select(
udelay(1); /* wingel -- wait two bus deskew delay >2*45ns */
/* Reset BSY */
- NCR5380_write(INITIATOR_COMMAND_REG, (ICR_BASE | ICR_ASSERT_DATA |
- ICR_ASSERT_ATN | ICR_ASSERT_SEL));
+ NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA |
+ ICR_ASSERT_ATN | ICR_ASSERT_SEL);
/*
* Something weird happens when we cease to drive BSY - looks
@@ -1462,7 +1462,7 @@ static struct scsi_cmnd *NCR5380_select(
hostdata->connected = cmd;
#ifndef SUPPORT_TAGS
- hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);
+ hostdata->busy[cmd->device->id] |= 1 << cmd->device->lun;
#endif
#ifdef SUN3_SCSI_VME
dregs->csr |= CSR_INTR;
@@ -1558,13 +1558,13 @@ static int NCR5380_transfer_pio(struct S
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA);
NCR5380_dprint(NDEBUG_PIO, instance);
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
- ICR_ASSERT_DATA | ICR_ASSERT_ACK);
+ ICR_ASSERT_DATA | ICR_ASSERT_ACK);
} else {
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
- ICR_ASSERT_DATA | ICR_ASSERT_ATN);
+ ICR_ASSERT_DATA | ICR_ASSERT_ATN);
NCR5380_dprint(NDEBUG_PIO, instance);
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
- ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_ACK);
+ ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_ACK);
}
} else {
NCR5380_dprint(NDEBUG_PIO, instance);
@@ -1892,11 +1892,11 @@ static void NCR5380_information_transfer
NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp));
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN |
- ICR_ASSERT_ACK);
+ ICR_ASSERT_ACK);
while (NCR5380_read(STATUS_REG) & SR_REQ)
;
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
- ICR_ASSERT_ATN);
+ ICR_ASSERT_ATN);
sink = 0;
continue;
}
@@ -1985,8 +1985,8 @@ static void NCR5380_information_transfer
{
spin_unlock_irq(&hostdata->lock);
NCR5380_transfer_pio(instance, &phase,
- (int *)&cmd->SCp.this_residual,
- (unsigned char **)&cmd->SCp.ptr);
+ (int *)&cmd->SCp.this_residual,
+ (unsigned char **)&cmd->SCp.ptr);
spin_lock_irq(&hostdata->lock);
}
#if defined(CONFIG_SUN3) && defined(REAL_DMA)
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Finn Thain <fthain@telegraphics.com.au> |
|---|---|
| Date | 2016-01-03 06:30 +0100 |
| Subject | [PATCH v4 77/78] ncr5380: Fix wait for 53C80 registers registers after PDMA |
| Message-ID | <qMJoV-1cG-89@gated-at.bofh.it> |
| In reply to | #1300181 |
From: Ondrej Zary <linux@rainbow-software.org>
The check for 53C80 registers accessibility was commented out because
it was broken (inverted). Fix and enable it.
Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
---
drivers/scsi/g_NCR5380.c | 37 ++++++-------------------------------
1 file changed, 6 insertions(+), 31 deletions(-)
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c 2016-01-03 16:04:54.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c 2016-01-03 16:04:55.000000000 +1100
@@ -609,14 +609,10 @@ static inline int NCR5380_pread(struct S
if (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ))
printk("53C400r: no 53C80 gated irq after transfer");
-#if 0
- /*
- * DON'T DO THIS - THEY NEVER ARRIVE!
- */
- printk("53C400r: Waiting for 53C80 registers\n");
- while (NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG)
+ /* wait for 53C80 registers to be available */
+ while (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG))
;
-#endif
+
if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER))
printk(KERN_ERR "53C400r: no end dma signal\n");
@@ -638,7 +634,6 @@ static inline int NCR5380_pwrite(struct
struct NCR5380_hostdata *hostdata = shost_priv(instance);
int blocks = len / 128;
int start = 0;
- int i;
NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
NCR5380_write(hostdata->c400_blk_cnt, blocks);
@@ -687,36 +682,16 @@ static inline int NCR5380_pwrite(struct
blocks--;
}
-#if 0
- printk("53C400w: waiting for registers to be available\n");
- THEY NEVER DO ! while (NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG);
- printk("53C400w: Got em\n");
-#endif
-
- /* Let's wait for this instead - could be ugly */
- /* All documentation says to check for this. Maybe my hardware is too
- * fast. Waiting for it seems to work fine! KLL
- */
- while (!(i = NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ)) {
+ /* wait for 53C80 registers to be available */
+ while (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG)) {
udelay(4); /* DTC436 chip hangs without this */
/* FIXME - no timeout */
}
- /*
- * I know. i is certainly != 0 here but the loop is new. See previous
- * comment.
- */
- if (i) {
- if (!((i = NCR5380_read(BUS_AND_STATUS_REG)) & BASR_END_DMA_TRANSFER))
- printk(KERN_ERR "53C400w: No END OF DMA bit - WHOOPS! BASR=%0x\n", i);
- } else
- printk(KERN_ERR "53C400w: no 53C80 gated irq after transfer (last block)\n");
-
-#if 0
if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER)) {
printk(KERN_ERR "53C400w: no end dma signal\n");
}
-#endif
+
while (!(NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT))
; // TIMEOUT
return 0;
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Finn Thain <fthain@telegraphics.com.au> |
|---|---|
| Date | 2016-01-03 06:30 +0100 |
| Subject | [PATCH v4 61/78] ncr5380: Fix EH during arbitration and selection |
| Message-ID | <qMJoV-1cG-87@gated-at.bofh.it> |
| In reply to | #1300181 |
During arbitration and selection, the relevant command is invisible to
exception handlers and can be found only in a pointer on the stack of a
different thread.
When eh_abort_handler can't find a given command, it can't decide whether
that command was completed already or is still in arbitration or selection
phase. But it must return either SUCCESS (e.g. command completed earlier)
or FAILED (could not abort the nexus, try bus reset).
The solution is to make sure all commands belonging to the LLD are always
visible to exception handlers. Add another scsi_cmnd pointer to the
hostdata struct to track the command in arbitration or selection phase.
Replace 'retain_dma_irq' with the new 'selecting' pointer, to bring
atari_NCR5380.c into line with NCR5380.c.
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Tested-by: Ondrej Zary <linux@rainbow-software.org>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
---
drivers/scsi/NCR5380.c | 76 +++++++++++++++++++++++++++++----------
drivers/scsi/NCR5380.h | 4 +-
drivers/scsi/atari_NCR5380.c | 82 +++++++++++++++++++++++++++++++------------
3 files changed, 119 insertions(+), 43 deletions(-)
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c 2016-01-03 16:04:28.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c 2016-01-03 16:04:30.000000000 +1100
@@ -912,9 +912,9 @@ static void NCR5380_main(struct work_str
* entire unit.
*/
- if (!NCR5380_select(instance, cmd)) {
- dsprintk(NDEBUG_MAIN, instance, "main: selected target %d for command %p\n",
- scmd_id(cmd), cmd);
+ cmd = NCR5380_select(instance, cmd);
+ if (!cmd) {
+ dsprintk(NDEBUG_MAIN, instance, "main: select complete\n");
} else {
dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES, instance,
"main: select failed, returning %p to queue\n", cmd);
@@ -1061,9 +1061,9 @@ static irqreturn_t NCR5380_intr(int irq,
* Inputs : instance - instantiation of the 5380 driver on which this
* target lives, cmd - SCSI command to execute.
*
- * Returns : -1 if selection failed but should be retried.
- * 0 if selection failed and should not be retried.
- * 0 if selection succeeded completely (hostdata->connected == cmd).
+ * Returns cmd if selection failed but should be retried,
+ * NULL if selection failed and should not be retried, or
+ * NULL if selection succeeded (hostdata->connected == cmd).
*
* Side effects :
* If bus busy, arbitration failed, etc, NCR5380_select() will exit
@@ -1081,7 +1081,8 @@ static irqreturn_t NCR5380_intr(int irq,
* Locks: caller holds hostdata lock in IRQ mode
*/
-static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
+static struct scsi_cmnd *NCR5380_select(struct Scsi_Host *instance,
+ struct scsi_cmnd *cmd)
{
struct NCR5380_hostdata *hostdata = shost_priv(instance);
unsigned char tmp[3], phase;
@@ -1092,6 +1093,15 @@ static int NCR5380_select(struct Scsi_Ho
NCR5380_dprint(NDEBUG_ARBITRATION, instance);
dprintk(NDEBUG_ARBITRATION, "scsi%d : starting arbitration, id = %d\n", instance->host_no, instance->this_id);
+ /*
+ * Arbitration and selection phases are slow and involve dropping the
+ * lock, so we have to watch out for EH. An exception handler may
+ * change 'selecting' to NULL. This function will then return NULL
+ * so that the caller will forget about 'cmd'. (During information
+ * transfer phases, EH may change 'connected' to NULL.)
+ */
+ hostdata->selecting = cmd;
+
/*
* Set the phase bits to 0, otherwise the NCR5380 won't drive the
* data bus during SELECTION.
@@ -1117,13 +1127,13 @@ static int NCR5380_select(struct Scsi_Ho
spin_lock_irq(&hostdata->lock);
if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE)) {
/* Reselection interrupt */
- return -1;
+ goto out;
}
if (err < 0) {
NCR5380_write(MODE_REG, MR_BASE);
shost_printk(KERN_ERR, instance,
"select: arbitration timeout\n");
- return -1;
+ goto out;
}
spin_unlock_irq(&hostdata->lock);
@@ -1135,7 +1145,7 @@ static int NCR5380_select(struct Scsi_Ho
NCR5380_write(MODE_REG, MR_BASE);
dprintk(NDEBUG_ARBITRATION, "scsi%d : lost arbitration, deasserting MR_ARBITRATE\n", instance->host_no);
spin_lock_irq(&hostdata->lock);
- return -1;
+ goto out;
}
/* After/during arbitration, BSY should be asserted.
@@ -1159,7 +1169,13 @@ static int NCR5380_select(struct Scsi_Ho
/* NCR5380_reselect() clears MODE_REG after a reselection interrupt */
if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE))
- return -1;
+ goto out;
+
+ if (!hostdata->selecting) {
+ NCR5380_write(MODE_REG, MR_BASE);
+ NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+ goto out;
+ }
dprintk(NDEBUG_ARBITRATION, "scsi%d : won arbitration\n", instance->host_no);
@@ -1232,18 +1248,21 @@ static int NCR5380_select(struct Scsi_Ho
if (!hostdata->connected)
NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
printk("scsi%d : reselection after won arbitration?\n", instance->host_no);
- return -1;
+ goto out;
}
if (err < 0) {
spin_lock_irq(&hostdata->lock);
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
- cmd->result = DID_BAD_TARGET << 16;
- complete_cmd(instance, cmd);
NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
- dprintk(NDEBUG_SELECTION, "scsi%d : target did not respond within 250ms\n",
- instance->host_no);
- return 0;
+ /* Can't touch cmd if it has been reclaimed by the scsi ML */
+ if (hostdata->selecting) {
+ cmd->result = DID_BAD_TARGET << 16;
+ complete_cmd(instance, cmd);
+ dsprintk(NDEBUG_SELECTION, instance, "target did not respond within 250ms\n");
+ cmd = NULL;
+ }
+ goto out;
}
/*
@@ -1279,7 +1298,11 @@ static int NCR5380_select(struct Scsi_Ho
shost_printk(KERN_ERR, instance, "select: REQ timeout\n");
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
- return -1;
+ goto out;
+ }
+ if (!hostdata->selecting) {
+ do_abort(instance);
+ goto out;
}
dprintk(NDEBUG_SELECTION, "scsi%d : target %d selected, going into MESSAGE OUT phase.\n", instance->host_no, cmd->device->id);
@@ -1300,7 +1323,13 @@ static int NCR5380_select(struct Scsi_Ho
initialize_SCp(cmd);
- return 0;
+ cmd = NULL;
+
+out:
+ if (!hostdata->selecting)
+ return NULL;
+ hostdata->selecting = NULL;
+ return cmd;
}
/*
@@ -2352,6 +2381,15 @@ static int NCR5380_abort(struct scsi_cmn
cmd->scsi_done(cmd); /* No tag or busy flag to worry about */
}
+ if (hostdata->selecting == cmd) {
+ dsprintk(NDEBUG_ABORT, instance,
+ "abort: cmd %p == selecting\n", cmd);
+ hostdata->selecting = NULL;
+ cmd->result = DID_ABORT << 16;
+ complete_cmd(instance, cmd);
+ goto out;
+ }
+
if (list_del_cmd(&hostdata->disconnected, cmd)) {
dsprintk(NDEBUG_ABORT, instance,
"abort: removed %p from disconnected list\n", cmd);
Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h 2016-01-03 16:04:25.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h 2016-01-03 16:04:30.000000000 +1100
@@ -255,6 +255,7 @@ struct NCR5380_hostdata {
#endif
unsigned char last_message; /* last message OUT */
struct scsi_cmnd *connected; /* currently connected cmnd */
+ struct scsi_cmnd *selecting; /* cmnd to be connected */
struct list_head unissued; /* waiting to be issued */
struct list_head autosense; /* priority issue queue */
struct list_head disconnected; /* waiting for reconnect */
@@ -265,7 +266,6 @@ struct NCR5380_hostdata {
char info[256];
int read_overruns; /* number of bytes to cut from a
* transfer to handle chip overruns */
- int retain_dma_intr;
struct work_struct main_task;
#ifdef SUPPORT_TAGS
struct tag_alloc TagAlloc[8][8]; /* 8 targets and 8 LUNs */
@@ -329,7 +329,7 @@ static irqreturn_t NCR5380_intr(int irq,
static void NCR5380_main(struct work_struct *work);
static const char *NCR5380_info(struct Scsi_Host *instance);
static void NCR5380_reselect(struct Scsi_Host *instance);
-static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd);
+static struct scsi_cmnd *NCR5380_select(struct Scsi_Host *, struct scsi_cmnd *);
#if defined(PSEUDO_DMA) || defined(REAL_DMA) || defined(REAL_DMA_POLL)
static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase, int *count, unsigned char **data);
#endif
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c 2016-01-03 16:04:28.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c 2016-01-03 16:04:30.000000000 +1100
@@ -885,7 +885,7 @@ static inline void maybe_release_dma_irq
list_empty(&hostdata->unissued) &&
list_empty(&hostdata->autosense) &&
!hostdata->connected &&
- !hostdata->retain_dma_intr)
+ !hostdata->selecting)
NCR5380_release_dma_irq(instance);
}
@@ -1006,14 +1006,11 @@ static void NCR5380_main(struct work_str
#ifdef SUPPORT_TAGS
cmd_get_tag(cmd, cmd->cmnd[0] != REQUEST_SENSE);
#endif
- hostdata->retain_dma_intr++;
- if (!NCR5380_select(instance, cmd)) {
- dsprintk(NDEBUG_MAIN, instance, "main: selected target %d for command %p\n",
- scmd_id(cmd), cmd);
- hostdata->retain_dma_intr--;
+ cmd = NCR5380_select(instance, cmd);
+ if (!cmd) {
+ dsprintk(NDEBUG_MAIN, instance, "main: select complete\n");
maybe_release_dma_irq(instance);
} else {
- hostdata->retain_dma_intr--;
dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES, instance,
"main: select failed, returning %p to queue\n", cmd);
requeue_cmd(instance, cmd);
@@ -1241,9 +1238,9 @@ static irqreturn_t NCR5380_intr(int irq,
* Inputs : instance - instantiation of the 5380 driver on which this
* target lives, cmd - SCSI command to execute.
*
- * Returns : -1 if selection failed but should be retried.
- * 0 if selection failed and should not be retried.
- * 0 if selection succeeded completely (hostdata->connected == cmd).
+ * Returns cmd if selection failed but should be retried,
+ * NULL if selection failed and should not be retried, or
+ * NULL if selection succeeded (hostdata->connected == cmd).
*
* Side effects :
* If bus busy, arbitration failed, etc, NCR5380_select() will exit
@@ -1259,7 +1256,8 @@ static irqreturn_t NCR5380_intr(int irq,
* cmd->result host byte set to DID_BAD_TARGET.
*/
-static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
+static struct scsi_cmnd *NCR5380_select(struct Scsi_Host *instance,
+ struct scsi_cmnd *cmd)
{
struct NCR5380_hostdata *hostdata = shost_priv(instance);
unsigned char tmp[3], phase;
@@ -1272,6 +1270,15 @@ static int NCR5380_select(struct Scsi_Ho
instance->this_id);
/*
+ * Arbitration and selection phases are slow and involve dropping the
+ * lock, so we have to watch out for EH. An exception handler may
+ * change 'selecting' to NULL. This function will then return NULL
+ * so that the caller will forget about 'cmd'. (During information
+ * transfer phases, EH may change 'connected' to NULL.)
+ */
+ hostdata->selecting = cmd;
+
+ /*
* Set the phase bits to 0, otherwise the NCR5380 won't drive the
* data bus during SELECTION.
*/
@@ -1296,13 +1303,13 @@ static int NCR5380_select(struct Scsi_Ho
spin_lock_irq(&hostdata->lock);
if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE)) {
/* Reselection interrupt */
- return -1;
+ goto out;
}
if (err < 0) {
NCR5380_write(MODE_REG, MR_BASE);
shost_printk(KERN_ERR, instance,
"select: arbitration timeout\n");
- return -1;
+ goto out;
}
spin_unlock_irq(&hostdata->lock);
@@ -1317,7 +1324,7 @@ static int NCR5380_select(struct Scsi_Ho
dprintk(NDEBUG_ARBITRATION, "scsi%d: lost arbitration, deasserting MR_ARBITRATE\n",
HOSTNO);
spin_lock_irq(&hostdata->lock);
- return -1;
+ goto out;
}
/* After/during arbitration, BSY should be asserted.
@@ -1341,7 +1348,13 @@ static int NCR5380_select(struct Scsi_Ho
/* NCR5380_reselect() clears MODE_REG after a reselection interrupt */
if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE))
- return -1;
+ goto out;
+
+ if (!hostdata->selecting) {
+ NCR5380_write(MODE_REG, MR_BASE);
+ NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+ goto out;
+ }
dprintk(NDEBUG_ARBITRATION, "scsi%d: won arbitration\n", HOSTNO);
@@ -1417,17 +1430,21 @@ static int NCR5380_select(struct Scsi_Ho
NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
printk(KERN_ERR "scsi%d: reselection after won arbitration?\n",
HOSTNO);
- return -1;
+ goto out;
}
if (err < 0) {
spin_lock_irq(&hostdata->lock);
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
- cmd->result = DID_BAD_TARGET << 16;
- complete_cmd(instance, cmd);
NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
- dprintk(NDEBUG_SELECTION, "scsi%d: target did not respond within 250ms\n", HOSTNO);
- return 0;
+ /* Can't touch cmd if it has been reclaimed by the scsi ML */
+ if (hostdata->selecting) {
+ cmd->result = DID_BAD_TARGET << 16;
+ complete_cmd(instance, cmd);
+ dsprintk(NDEBUG_SELECTION, instance, "target did not respond within 250ms\n");
+ cmd = NULL;
+ }
+ goto out;
}
/*
@@ -1463,7 +1480,11 @@ static int NCR5380_select(struct Scsi_Ho
shost_printk(KERN_ERR, instance, "select: REQ timeout\n");
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
- return -1;
+ goto out;
+ }
+ if (!hostdata->selecting) {
+ do_abort(instance);
+ goto out;
}
dprintk(NDEBUG_SELECTION, "scsi%d: target %d selected, going into MESSAGE OUT phase.\n",
@@ -1499,7 +1520,13 @@ static int NCR5380_select(struct Scsi_Ho
initialize_SCp(cmd);
- return 0;
+ cmd = NULL;
+
+out:
+ if (!hostdata->selecting)
+ return NULL;
+ hostdata->selecting = NULL;
+ return cmd;
}
/*
@@ -2563,6 +2590,15 @@ static int NCR5380_abort(struct scsi_cmn
cmd->scsi_done(cmd); /* No tag or busy flag to worry about */
}
+ if (hostdata->selecting == cmd) {
+ dsprintk(NDEBUG_ABORT, instance,
+ "abort: cmd %p == selecting\n", cmd);
+ hostdata->selecting = NULL;
+ cmd->result = DID_ABORT << 16;
+ complete_cmd(instance, cmd);
+ goto out;
+ }
+
if (list_del_cmd(&hostdata->disconnected, cmd)) {
dsprintk(NDEBUG_ABORT, instance,
"abort: removed %p from disconnected list\n", cmd);
@@ -2680,6 +2716,8 @@ static int NCR5380_bus_reset(struct scsi
* commands!
*/
+ hostdata->selecting = NULL;
+
if (hostdata->connected)
dsprintk(NDEBUG_ABORT, instance, "reset aborted a connected command\n");
hostdata->connected = NULL;
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Finn Thain <fthain@telegraphics.com.au> |
|---|---|
| Date | 2016-01-03 06:30 +0100 |
| Subject | [PATCH v4 03/78] ncr5380: Eliminate PDEBUG*, TDEBUG* and DTCDEBUG* macros |
| Message-ID | <qMJoV-1cG-91@gated-at.bofh.it> |
| In reply to | #1300181 |
Replace {P,T,DTC}DEBUG_INIT with NDEBUG_INIT. Remove dead debugging
code, including code that's conditional upon *DEBUG_TRANSFER.
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
---
drivers/scsi/dtc.c | 18 ++++++------------
drivers/scsi/dtc.h | 27 ---------------------------
drivers/scsi/pas16.c | 21 +++++++--------------
drivers/scsi/pas16.h | 16 ----------------
drivers/scsi/t128.c | 18 ++++++------------
drivers/scsi/t128.h | 16 ----------------
6 files changed, 19 insertions(+), 97 deletions(-)
Index: linux/drivers/scsi/dtc.c
===================================================================
--- linux.orig/drivers/scsi/dtc.c 2016-01-03 16:02:42.000000000 +1100
+++ linux/drivers/scsi/dtc.c 2016-01-03 16:02:47.000000000 +1100
@@ -205,9 +205,8 @@ static int __init dtc_detect(struct scsi
addr = 0;
} else
for (; !addr && (current_base < NO_BASES); ++current_base) {
-#if (DTCDEBUG & DTCDEBUG_INIT)
- printk(KERN_DEBUG "scsi-dtc : probing address %08x\n", bases[current_base].address);
-#endif
+ dprintk(NDEBUG_INIT, "dtc: probing address 0x%08x\n",
+ (unsigned int)bases[current_base].address);
if (bases[current_base].noauto)
continue;
base = ioremap(bases[current_base].address, 0x2000);
@@ -216,18 +215,14 @@ static int __init dtc_detect(struct scsi
for (sig = 0; sig < NO_SIGNATURES; ++sig) {
if (check_signature(base + signatures[sig].offset, signatures[sig].string, strlen(signatures[sig].string))) {
addr = bases[current_base].address;
-#if (DTCDEBUG & DTCDEBUG_INIT)
- printk(KERN_DEBUG "scsi-dtc : detected board.\n");
-#endif
+ dprintk(NDEBUG_INIT, "dtc: detected board\n");
goto found;
}
}
iounmap(base);
}
-#if defined(DTCDEBUG) && (DTCDEBUG & DTCDEBUG_INIT)
- printk(KERN_DEBUG "scsi-dtc : base = %08x\n", addr);
-#endif
+ dprintk(NDEBUG_INIT, "dtc: addr = 0x%08x\n", addr);
if (!addr)
break;
@@ -271,9 +266,8 @@ found:
printk(KERN_WARNING "scsi%d : interrupts not used. Might as well not jumper it.\n", instance->host_no);
instance->irq = NO_IRQ;
#endif
-#if defined(DTCDEBUG) && (DTCDEBUG & DTCDEBUG_INIT)
- printk("scsi%d : irq = %d\n", instance->host_no, instance->irq);
-#endif
+ dprintk(NDEBUG_INIT, "scsi%d : irq = %d\n",
+ instance->host_no, instance->irq);
++current_override;
++count;
Index: linux/drivers/scsi/dtc.h
===================================================================
--- linux.orig/drivers/scsi/dtc.h 2016-01-03 16:02:39.000000000 +1100
+++ linux/drivers/scsi/dtc.h 2016-01-03 16:02:47.000000000 +1100
@@ -10,10 +10,6 @@
#ifndef DTC3280_H
#define DTC3280_H
-#define DTCDEBUG 0
-#define DTCDEBUG_INIT 0x1
-#define DTCDEBUG_TRANSFER 0x2
-
#ifndef CMD_PER_LUN
#define CMD_PER_LUN 2
#endif
@@ -33,31 +29,8 @@
#define DTC_address(reg) (base + DTC_5380_OFFSET + reg)
-#define dbNCR5380_read(reg) \
- (rval=readb(DTC_address(reg)), \
- (((unsigned char) printk("DTC : read register %d at addr %p is: %02x\n"\
- , (reg), DTC_address(reg), rval)), rval ) )
-
-#define dbNCR5380_write(reg, value) do { \
- printk("DTC : write %02x to register %d at address %p\n", \
- (value), (reg), DTC_address(reg)); \
- writeb(value, DTC_address(reg));} while(0)
-
-
-#if !(DTCDEBUG & DTCDEBUG_TRANSFER)
#define NCR5380_read(reg) (readb(DTC_address(reg)))
#define NCR5380_write(reg, value) (writeb(value, DTC_address(reg)))
-#else
-#define NCR5380_read(reg) (readb(DTC_address(reg)))
-#define xNCR5380_read(reg) \
- (((unsigned char) printk("DTC : read register %d at address %p\n"\
- , (reg), DTC_address(reg))), readb(DTC_address(reg)))
-
-#define NCR5380_write(reg, value) do { \
- printk("DTC : write %02x to register %d at address %p\n", \
- (value), (reg), DTC_address(reg)); \
- writeb(value, DTC_address(reg));} while(0)
-#endif
#define NCR5380_intr dtc_intr
#define NCR5380_queue_command dtc_queue_command
Index: linux/drivers/scsi/pas16.c
===================================================================
--- linux.orig/drivers/scsi/pas16.c 2016-01-03 16:02:42.000000000 +1100
+++ linux/drivers/scsi/pas16.c 2016-01-03 16:02:47.000000000 +1100
@@ -1,6 +1,5 @@
#define PSEUDO_DMA
#define UNSAFE /* Not unsafe for PAS16 -- use it */
-#define PDEBUG 0
/*
* This driver adapted from Drew Eckhardt's Trantor T128 driver
@@ -377,23 +376,18 @@ static int __init pas16_detect(struct sc
}
else
for (; !io_port && (current_base < NO_BASES); ++current_base) {
-#if (PDEBUG & PDEBUG_INIT)
- printk("scsi-pas16 : probing io_port %04x\n", (unsigned int) bases[current_base].io_port);
-#endif
+ dprintk(NDEBUG_INIT, "pas16: probing io_port 0x%04x\n",
+ (unsigned int)bases[current_base].io_port);
if ( !bases[current_base].noauto &&
pas16_hw_detect( current_base ) ){
io_port = bases[current_base].io_port;
init_board( io_port, default_irqs[ current_base ], 0 );
-#if (PDEBUG & PDEBUG_INIT)
- printk("scsi-pas16 : detected board.\n");
-#endif
+ dprintk(NDEBUG_INIT, "pas16: detected board\n");
}
}
-
-#if defined(PDEBUG) && (PDEBUG & PDEBUG_INIT)
- printk("scsi-pas16 : io_port = %04x\n", (unsigned int) io_port);
-#endif
+ dprintk(NDEBUG_INIT, "pas16: io_port = 0x%04x\n",
+ (unsigned int)io_port);
if (!io_port)
break;
@@ -431,9 +425,8 @@ static int __init pas16_detect(struct sc
outb( (inb(io_port + IO_CONFIG_3) & 0x0f), io_port + IO_CONFIG_3 );
}
-#if defined(PDEBUG) && (PDEBUG & PDEBUG_INIT)
- printk("scsi%d : irq = %d\n", instance->host_no, instance->irq);
-#endif
+ dprintk(NDEBUG_INIT, "scsi%d : irq = %d\n",
+ instance->host_no, instance->irq);
++current_override;
++count;
Index: linux/drivers/scsi/pas16.h
===================================================================
--- linux.orig/drivers/scsi/pas16.h 2016-01-03 16:02:39.000000000 +1100
+++ linux/drivers/scsi/pas16.h 2016-01-03 16:02:47.000000000 +1100
@@ -24,9 +24,6 @@
#ifndef PAS16_H
#define PAS16_H
-#define PDEBUG_INIT 0x1
-#define PDEBUG_TRANSFER 0x2
-
#define PAS16_DEFAULT_BASE_1 0x388
#define PAS16_DEFAULT_BASE_2 0x384
#define PAS16_DEFAULT_BASE_3 0x38c
@@ -120,21 +117,8 @@
#define PAS16_io_port(reg) ( io_port + pas16_offset[(reg)] )
-#if !(PDEBUG & PDEBUG_TRANSFER)
#define NCR5380_read(reg) ( inb(PAS16_io_port(reg)) )
#define NCR5380_write(reg, value) ( outb((value),PAS16_io_port(reg)) )
-#else
-#define NCR5380_read(reg) \
- (((unsigned char) printk("scsi%d : read register %d at io_port %04x\n"\
- , instance->hostno, (reg), PAS16_io_port(reg))), inb( PAS16_io_port(reg)) )
-
-#define NCR5380_write(reg, value) \
- (printk("scsi%d : write %02x to register %d at io_port %04x\n", \
- instance->hostno, (value), (reg), PAS16_io_port(reg)), \
- outb( (value),PAS16_io_port(reg) ) )
-
-#endif
-
#define NCR5380_intr pas16_intr
#define do_NCR5380_intr do_pas16_intr
Index: linux/drivers/scsi/t128.c
===================================================================
--- linux.orig/drivers/scsi/t128.c 2016-01-03 16:02:42.000000000 +1100
+++ linux/drivers/scsi/t128.c 2016-01-03 16:02:47.000000000 +1100
@@ -182,9 +182,8 @@ static int __init t128_detect(struct scs
base = 0;
} else
for (; !base && (current_base < NO_BASES); ++current_base) {
-#if (TDEBUG & TDEBUG_INIT)
- printk("scsi-t128 : probing address %08x\n", bases[current_base].address);
-#endif
+ dprintk(NDEBUG_INIT, "t128: probing address 0x%08x\n",
+ bases[current_base].address);
if (bases[current_base].noauto)
continue;
p = ioremap(bases[current_base].address, 0x2000);
@@ -195,17 +194,13 @@ static int __init t128_detect(struct scs
signatures[sig].string,
strlen(signatures[sig].string))) {
base = bases[current_base].address;
-#if (TDEBUG & TDEBUG_INIT)
- printk("scsi-t128 : detected board.\n");
-#endif
+ dprintk(NDEBUG_INIT, "t128: detected board\n");
goto found;
}
iounmap(p);
}
-#if defined(TDEBUG) && (TDEBUG & TDEBUG_INIT)
- printk("scsi-t128 : base = %08x\n", (unsigned int) base);
-#endif
+ dprintk(NDEBUG_INIT, "t128: base = 0x%08x\n", (unsigned int)base);
if (!base)
break;
@@ -242,9 +237,8 @@ found:
printk("scsi%d : please jumper the board for a free IRQ.\n", instance->host_no);
}
-#if defined(TDEBUG) && (TDEBUG & TDEBUG_INIT)
- printk("scsi%d : irq = %d\n", instance->host_no, instance->irq);
-#endif
+ dprintk(NDEBUG_INIT, "scsi%d: irq = %d\n",
+ instance->host_no, instance->irq);
++current_override;
++count;
Index: linux/drivers/scsi/t128.h
===================================================================
--- linux.orig/drivers/scsi/t128.h 2016-01-03 16:02:39.000000000 +1100
+++ linux/drivers/scsi/t128.h 2016-01-03 16:02:47.000000000 +1100
@@ -23,10 +23,6 @@
#ifndef T128_H
#define T128_H
-#define TDEBUG 0
-#define TDEBUG_INIT 0x1
-#define TDEBUG_TRANSFER 0x2
-
/*
* The trantor boards are memory mapped. They use an NCR5380 or
* equivalent (my sample board had part second sourced from ZILOG).
@@ -92,20 +88,8 @@
#define T128_address(reg) (base + T_5380_OFFSET + ((reg) * 0x20))
-#if !(TDEBUG & TDEBUG_TRANSFER)
#define NCR5380_read(reg) readb(T128_address(reg))
#define NCR5380_write(reg, value) writeb((value),(T128_address(reg)))
-#else
-#define NCR5380_read(reg) \
- (((unsigned char) printk("scsi%d : read register %d at address %08x\n"\
- , instance->hostno, (reg), T128_address(reg))), readb(T128_address(reg)))
-
-#define NCR5380_write(reg, value) { \
- printk("scsi%d : write %02x to register %d at address %08x\n", \
- instance->hostno, (value), (reg), T128_address(reg)); \
- writeb((value), (T128_address(reg))); \
-}
-#endif
#define NCR5380_intr t128_intr
#define do_NCR5380_intr do_t128_intr
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Finn Thain <fthain@telegraphics.com.au> |
|---|---|
| Date | 2016-01-03 06:30 +0100 |
| Subject | [PATCH v4 66/78] ncr5380: Fix soft lockups |
| Message-ID | <qMJoV-1cG-93@gated-at.bofh.it> |
| In reply to | #1300181 |
Because of the rudimentary design of the chip, it is necessary to poll the
SCSI bus signals during PIO and this tends to hog the CPU. The driver will
accept new commands while others execute, and this causes a soft lockup
because the workqueue item will not terminate until the issue queue is
emptied.
When exercising dmx3191d using sequential IO from dd, the driver is sent
512 KiB WRITE commands and 128 KiB READs. For a PIO transfer, the rate is
is only about 300 KiB/s, so these are long-running commands. And although
PDMA may run at several MiB/s, interrupts are disabled for the duration
of the transfer.
Fix the unresponsiveness and soft lockup issues by calling cond_resched()
after each command is completed and by limiting max_sectors for drivers
that don't implement real DMA.
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Tested-by: Ondrej Zary <linux@rainbow-software.org>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
---
Changed since v2:
- Moved max_sectors initialization to wrapper drivers. It isn't really
relevant to the core driver and compile-time configuration using macros
like REAL_DMA should be avoided.
---
drivers/scsi/NCR5380.c | 6 ++++--
drivers/scsi/arm/cumana_1.c | 1 +
drivers/scsi/arm/oak.c | 1 +
drivers/scsi/atari_NCR5380.c | 6 ++++--
drivers/scsi/dmx3191d.c | 1 +
drivers/scsi/dtc.c | 1 +
drivers/scsi/g_NCR5380.c | 1 +
drivers/scsi/mac_scsi.c | 1 +
drivers/scsi/pas16.c | 1 +
drivers/scsi/t128.c | 1 +
10 files changed, 16 insertions(+), 4 deletions(-)
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c 2016-01-03 16:04:34.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c 2016-01-03 16:04:38.000000000 +1100
@@ -890,10 +890,10 @@ static void NCR5380_main(struct work_str
struct scsi_cmnd *cmd;
int done;
- spin_lock_irq(&hostdata->lock);
do {
done = 1;
+ spin_lock_irq(&hostdata->lock);
while (!hostdata->connected &&
(cmd = dequeue_next_cmd(instance))) {
@@ -930,8 +930,10 @@ static void NCR5380_main(struct work_str
NCR5380_information_transfer(instance);
done = 0;
}
+ spin_unlock_irq(&hostdata->lock);
+ if (!done)
+ cond_resched();
} while (!done);
- spin_unlock_irq(&hostdata->lock);
}
#ifndef DONT_USE_INTR
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c 2016-01-03 16:04:36.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c 2016-01-03 16:04:38.000000000 +1100
@@ -976,10 +976,10 @@ static void NCR5380_main(struct work_str
* alter queues and touch the Falcon lock.
*/
- spin_lock_irq(&hostdata->lock);
do {
done = 1;
+ spin_lock_irq(&hostdata->lock);
while (!hostdata->connected &&
(cmd = dequeue_next_cmd(instance))) {
@@ -1026,8 +1026,10 @@ static void NCR5380_main(struct work_str
NCR5380_information_transfer(instance);
done = 0;
}
+ spin_unlock_irq(&hostdata->lock);
+ if (!done)
+ cond_resched();
} while (!done);
- spin_unlock_irq(&hostdata->lock);
}
Index: linux/drivers/scsi/arm/cumana_1.c
===================================================================
--- linux.orig/drivers/scsi/arm/cumana_1.c 2016-01-03 16:04:20.000000000 +1100
+++ linux/drivers/scsi/arm/cumana_1.c 2016-01-03 16:04:38.000000000 +1100
@@ -209,6 +209,7 @@ static struct scsi_host_template cumanas
.use_clustering = DISABLE_CLUSTERING,
.proc_name = "CumanaSCSI-1",
.cmd_size = NCR5380_CMD_SIZE,
+ .max_sectors = 128,
};
static int cumanascsi1_probe(struct expansion_card *ec,
Index: linux/drivers/scsi/arm/oak.c
===================================================================
--- linux.orig/drivers/scsi/arm/oak.c 2016-01-03 16:04:20.000000000 +1100
+++ linux/drivers/scsi/arm/oak.c 2016-01-03 16:04:38.000000000 +1100
@@ -115,6 +115,7 @@ static struct scsi_host_template oakscsi
.use_clustering = DISABLE_CLUSTERING,
.proc_name = "oakscsi",
.cmd_size = NCR5380_CMD_SIZE,
+ .max_sectors = 128,
};
static int oakscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
Index: linux/drivers/scsi/dmx3191d.c
===================================================================
--- linux.orig/drivers/scsi/dmx3191d.c 2016-01-03 16:04:20.000000000 +1100
+++ linux/drivers/scsi/dmx3191d.c 2016-01-03 16:04:38.000000000 +1100
@@ -62,6 +62,7 @@ static struct scsi_host_template dmx3191
.cmd_per_lun = 2,
.use_clustering = DISABLE_CLUSTERING,
.cmd_size = NCR5380_CMD_SIZE,
+ .max_sectors = 128,
};
static int dmx3191d_probe_one(struct pci_dev *pdev,
Index: linux/drivers/scsi/dtc.c
===================================================================
--- linux.orig/drivers/scsi/dtc.c 2016-01-03 16:04:20.000000000 +1100
+++ linux/drivers/scsi/dtc.c 2016-01-03 16:04:38.000000000 +1100
@@ -453,5 +453,6 @@ static struct scsi_host_template driver_
.cmd_per_lun = 2,
.use_clustering = DISABLE_CLUSTERING,
.cmd_size = NCR5380_CMD_SIZE,
+ .max_sectors = 128,
};
#include "scsi_module.c"
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c 2016-01-03 16:04:20.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c 2016-01-03 16:04:38.000000000 +1100
@@ -729,6 +729,7 @@ static struct scsi_host_template driver_
.cmd_per_lun = 2,
.use_clustering = DISABLE_CLUSTERING,
.cmd_size = NCR5380_CMD_SIZE,
+ .max_sectors = 128,
};
#include "scsi_module.c"
Index: linux/drivers/scsi/mac_scsi.c
===================================================================
--- linux.orig/drivers/scsi/mac_scsi.c 2016-01-03 16:04:20.000000000 +1100
+++ linux/drivers/scsi/mac_scsi.c 2016-01-03 16:04:38.000000000 +1100
@@ -324,6 +324,7 @@ static struct scsi_host_template mac_scs
.cmd_per_lun = 2,
.use_clustering = DISABLE_CLUSTERING,
.cmd_size = NCR5380_CMD_SIZE,
+ .max_sectors = 128,
};
static int __init mac_scsi_probe(struct platform_device *pdev)
Index: linux/drivers/scsi/pas16.c
===================================================================
--- linux.orig/drivers/scsi/pas16.c 2016-01-03 16:04:20.000000000 +1100
+++ linux/drivers/scsi/pas16.c 2016-01-03 16:04:38.000000000 +1100
@@ -563,6 +563,7 @@ static struct scsi_host_template driver_
.cmd_per_lun = 2,
.use_clustering = DISABLE_CLUSTERING,
.cmd_size = NCR5380_CMD_SIZE,
+ .max_sectors = 128,
};
#include "scsi_module.c"
Index: linux/drivers/scsi/t128.c
===================================================================
--- linux.orig/drivers/scsi/t128.c 2016-01-03 16:04:20.000000000 +1100
+++ linux/drivers/scsi/t128.c 2016-01-03 16:04:38.000000000 +1100
@@ -407,5 +407,6 @@ static struct scsi_host_template driver_
.cmd_per_lun = 2,
.use_clustering = DISABLE_CLUSTERING,
.cmd_size = NCR5380_CMD_SIZE,
+ .max_sectors = 128,
};
#include "scsi_module.c"
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Finn Thain <fthain@telegraphics.com.au> |
|---|---|
| Date | 2016-01-03 06:40 +0100 |
| Subject | [PATCH v4 32/78] ncr5380: Fix bus phase in do_abort() |
| Message-ID | <qMJyx-1gX-3@gated-at.bofh.it> |
| In reply to | #1300181 |
NCR5380_poll_politely() returns either 0 (success) or -ETIMEDOUT. However,
in do_abort(), the return value is incorrectly taken to be the status
register value. This means that the bus is put into DATA OUT phase instead
of MESSAGE OUT. Fix this.
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Tested-by: Ondrej Zary <linux@rainbow-software.org>
---
drivers/scsi/NCR5380.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c 2016-01-03 16:03:41.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c 2016-01-03 16:03:42.000000000 +1100
@@ -1493,11 +1493,11 @@ static int do_abort(struct Scsi_Host *in
if (rc < 0)
return -1;
- tmp = (unsigned char)rc;
+ tmp = NCR5380_read(STATUS_REG) & PHASE_MASK;
NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp));
- if ((tmp & PHASE_MASK) != PHASE_MSGOUT) {
+ if (tmp != PHASE_MSGOUT) {
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN | ICR_ASSERT_ACK);
rc = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, 0, 3 * HZ);
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Finn Thain <fthain@telegraphics.com.au> |
|---|---|
| Date | 2016-01-03 06:40 +0100 |
| Subject | [PATCH v4 06/78] ncr5380: Remove NCR5380_instance_name macro |
| Message-ID | <qMJyx-1gX-1@gated-at.bofh.it> |
| In reply to | #1300181 |
This macro makes the code cryptic. Remove it. Signed-off-by: Finn Thain <fthain@telegraphics.com.au> Reviewed-by: Hannes Reinecke <hare@suse.com> Tested-by: Ondrej Zary <linux@rainbow-software.org> --- drivers/scsi/NCR5380.c | 2 +- drivers/scsi/g_NCR5380.c | 7 ++++--- drivers/scsi/g_NCR5380.h | 2 -- 3 files changed, 5 insertions(+), 6 deletions(-) Index: linux/drivers/scsi/g_NCR5380.c =================================================================== --- linux.orig/drivers/scsi/g_NCR5380.c 2016-01-03 16:02:56.000000000 +1100 +++ linux/drivers/scsi/g_NCR5380.c 2016-01-03 16:03:02.000000000 +1100 @@ -412,10 +412,11 @@ static int __init generic_NCR5380_detect continue; } - instance->NCR5380_instance_name = overrides[current_override].NCR5380_map_name; #ifndef SCSI_G_NCR5380_MEM + instance->io_port = overrides[current_override].NCR5380_map_name; instance->n_io_port = region_size; #else + instance->base = overrides[current_override].NCR5380_map_name; ((struct NCR5380_hostdata *)instance->hostdata)->iomem = iomem; #endif @@ -464,10 +465,10 @@ static int generic_NCR5380_release_resou NCR5380_exit(instance); #ifndef SCSI_G_NCR5380_MEM - release_region(instance->NCR5380_instance_name, instance->n_io_port); + release_region(instance->io_port, instance->n_io_port); #else iounmap(((struct NCR5380_hostdata *)instance->hostdata)->iomem); - release_mem_region(instance->NCR5380_instance_name, NCR5380_region_size); + release_mem_region(instance->base, NCR5380_region_size); #endif Index: linux/drivers/scsi/g_NCR5380.h =================================================================== --- linux.orig/drivers/scsi/g_NCR5380.h 2016-01-03 16:02:56.000000000 +1100 +++ linux/drivers/scsi/g_NCR5380.h 2016-01-03 16:03:02.000000000 +1100 @@ -36,7 +36,6 @@ #define NCR5380_map_type int #define NCR5380_map_name port -#define NCR5380_instance_name io_port #define NCR53C400_register_offset 0 #define NCR53C400_address_adjust 8 @@ -58,7 +57,6 @@ #define NCR5380_map_type unsigned long #define NCR5380_map_name base -#define NCR5380_instance_name base #define NCR53C400_register_offset 0x108 #define NCR53C400_address_adjust 0 #define NCR53C400_mem_base 0x3880 Index: linux/drivers/scsi/NCR5380.c =================================================================== --- linux.orig/drivers/scsi/NCR5380.c 2016-01-03 16:02:56.000000000 +1100 +++ linux/drivers/scsi/NCR5380.c 2016-01-03 16:03:02.000000000 +1100 @@ -790,7 +790,7 @@ static int NCR5380_init(struct Scsi_Host #ifdef NCR53C400 if (flags & FLAG_NCR53C400) - instance->NCR5380_instance_name += NCR53C400_address_adjust; + instance->io_port += NCR53C400_address_adjust; #endif hostdata->aborted = 0; -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Finn Thain <fthain@telegraphics.com.au> |
|---|---|
| Date | 2016-01-03 06:40 +0100 |
| Subject | [PATCH v4 34/78] atari_NCR5380: Use arbitration timeout |
| Message-ID | <qMJyx-1gX-5@gated-at.bofh.it> |
| In reply to | #1300181 |
Allow target selection to fail with a timeout instead of waiting in
infinite loops. This gets rid of the unused NCR_TIMEOUT macro, it is more
defensive and has proved helpful in debugging.
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Tested-by: Ondrej Zary <linux@rainbow-software.org>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
---
drivers/scsi/NCR5380.c | 44 ++++++++++++++++++---------------
drivers/scsi/atari_NCR5380.c | 57 ++++++++++++++++++-------------------------
2 files changed, 49 insertions(+), 52 deletions(-)
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c 2016-01-03 16:03:43.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c 2016-01-03 16:03:44.000000000 +1100
@@ -1412,6 +1412,7 @@ static int NCR5380_select(struct Scsi_Ho
int len;
int err;
unsigned long flags;
+ unsigned long timeout;
NCR5380_dprint(NDEBUG_ARBITRATION, instance);
dprintk(NDEBUG_ARBITRATION, "scsi%d: starting arbitration, id = %d\n", HOSTNO,
@@ -1436,42 +1437,28 @@ static int NCR5380_select(struct Scsi_Ho
NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask);
NCR5380_write(MODE_REG, MR_ARBITRATE);
- local_irq_restore(flags);
+ /* The chip now waits for BUS FREE phase. Then after the 800 ns
+ * Bus Free Delay, arbitration will begin.
+ */
- /* Wait for arbitration logic to complete */
-#if defined(NCR_TIMEOUT)
- {
- unsigned long timeout = jiffies + 2*NCR_TIMEOUT;
-
- while (!(NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_PROGRESS) &&
- time_before(jiffies, timeout) && !hostdata->connected)
- ;
- if (time_after_eq(jiffies, timeout)) {
- printk("scsi : arbitration timeout at %d\n", __LINE__);
+ local_irq_restore(flags);
+ timeout = jiffies + HZ;
+ while (1) {
+ if (time_is_before_jiffies(timeout)) {
NCR5380_write(MODE_REG, MR_BASE);
- NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
+ shost_printk(KERN_ERR, instance,
+ "select: arbitration timeout\n");
return -1;
}
+ if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE)) {
+ /* Reselection interrupt */
+ return -1;
+ }
+ if (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_PROGRESS)
+ break;
}
-#else /* NCR_TIMEOUT */
- while (!(NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_PROGRESS) &&
- !hostdata->connected)
- ;
-#endif
-
- dprintk(NDEBUG_ARBITRATION, "scsi%d: arbitration complete\n", HOSTNO);
-
- if (hostdata->connected) {
- NCR5380_write(MODE_REG, MR_BASE);
- return -1;
- }
- /*
- * The arbitration delay is 2.2us, but this is a minimum and there is
- * no maximum so we can safely sleep for ceil(2.2) usecs to accommodate
- * the integral nature of udelay().
- *
- */
+ /* The SCSI-2 arbitration delay is 2.4 us */
udelay(3);
/* Check for lost arbitration */
@@ -1634,8 +1621,14 @@ static int NCR5380_select(struct Scsi_Ho
*/
/* Wait for start of REQ/ACK handshake */
- while (!(NCR5380_read(STATUS_REG) & SR_REQ))
- ;
+
+ err = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ);
+ if (err < 0) {
+ shost_printk(KERN_ERR, instance, "select: REQ timeout\n");
+ NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+ NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
+ return -1;
+ }
dprintk(NDEBUG_SELECTION, "scsi%d: target %d selected, going into MESSAGE OUT phase.\n",
HOSTNO, cmd->device->id);
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c 2016-01-03 16:03:43.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c 2016-01-03 16:03:44.000000000 +1100
@@ -1083,6 +1083,7 @@ static int NCR5380_select(struct Scsi_Ho
unsigned char *data;
int len;
int err;
+ unsigned long timeout;
NCR5380_dprint(NDEBUG_ARBITRATION, instance);
dprintk(NDEBUG_ARBITRATION, "scsi%d : starting arbitration, id = %d\n", instance->host_no, instance->this_id);
@@ -1101,28 +1102,31 @@ static int NCR5380_select(struct Scsi_Ho
NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask);
NCR5380_write(MODE_REG, MR_ARBITRATE);
+ /* The chip now waits for BUS FREE phase. Then after the 800 ns
+ * Bus Free Delay, arbitration will begin.
+ */
- /* We can be relaxed here, interrupts are on, we are
- in workqueue context, the birds are singing in the trees */
spin_unlock_irq(instance->host_lock);
- err = NCR5380_poll_politely(instance, INITIATOR_COMMAND_REG, ICR_ARBITRATION_PROGRESS, ICR_ARBITRATION_PROGRESS, 5*HZ);
- spin_lock_irq(instance->host_lock);
- if (err < 0) {
- printk(KERN_DEBUG "scsi: arbitration timeout at %d\n", __LINE__);
- NCR5380_write(MODE_REG, MR_BASE);
- NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
- return -1;
+ timeout = jiffies + HZ;
+ while (1) {
+ if (time_is_before_jiffies(timeout)) {
+ NCR5380_write(MODE_REG, MR_BASE);
+ shost_printk(KERN_ERR, instance,
+ "select: arbitration timeout\n");
+ spin_lock_irq(instance->host_lock);
+ return -1;
+ }
+ spin_lock_irq(instance->host_lock);
+ if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE)) {
+ /* Reselection interrupt */
+ return -1;
+ }
+ if (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_PROGRESS)
+ break;
+ spin_unlock_irq(instance->host_lock);
}
- dprintk(NDEBUG_ARBITRATION, "scsi%d : arbitration complete\n", instance->host_no);
-
- /*
- * The arbitration delay is 2.2us, but this is a minimum and there is
- * no maximum so we can safely sleep for ceil(2.2) usecs to accommodate
- * the integral nature of udelay().
- *
- */
-
+ /* The SCSI-2 arbitration delay is 2.4 us */
udelay(3);
/* Check for lost arbitration */
@@ -1270,9 +1274,9 @@ static int NCR5380_select(struct Scsi_Ho
spin_unlock_irq(instance->host_lock);
err = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ);
spin_lock_irq(instance->host_lock);
-
if (err < 0) {
- printk(KERN_ERR "scsi%d: timeout at NCR5380.c:%d\n", instance->host_no, __LINE__);
+ shost_printk(KERN_ERR, instance, "select: REQ timeout\n");
+ NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
return -1;
}
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Finn Thain <fthain@telegraphics.com.au> |
|---|---|
| Date | 2016-01-03 06:40 +0100 |
| Subject | [PATCH v4 50/78] ncr5380: Change instance->host_lock to hostdata->lock |
| Message-ID | <qMJyx-1gX-7@gated-at.bofh.it> |
| In reply to | #1300181 |
NCR5380.c presently uses the instance->host_lock spin lock. Convert this
to a new spin lock that protects the NCR5380_hostdata struct.
atari_NCR5380.c previously used local_irq_save/restore() rather than a
spin lock. Convert this to hostdata->lock in irq mode. For SMP platforms,
the interrupt handler now also acquires the spin lock.
This brings all locking in the two core drivers into agreement.
Adding this locking also means that a bunch of volatile qualifiers can be
removed from the members of the NCR5380_hostdata struct. This is done in
a subsequent patch.
Proper locking will allow the abort handler to locate a command being
aborted. This is presently impossible if the abort handler is invoked when
the command has been moved from a queue to a pointer on the stack. (If
eh_abort_handler can't determine whether a command has been completed
or is still being processed then it can't decide whether to return
success or failure.)
The hostdata spin lock is now held when calling NCR5380_select() and
NCR5380_information_transfer(). Where possible, the lock is dropped for
polling and PIO transfers.
Clean up the now-redundant SELECT_ENABLE_REG writes, that used to provide
limited mutual exclusion between information_transfer() and reselect().
Accessing hostdata->connected without data races means taking the lock;
cleanup these accesses.
The new spin lock falls away for m68k and other UP builds, so this should
have little impact there. In the SMP case the new lock should be
uncontested even when the SCSI bus is contested.
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Tested-by: Ondrej Zary <linux@rainbow-software.org>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
---
drivers/scsi/NCR5380.c | 82 ++++++++++++++++----------
drivers/scsi/NCR5380.h | 1
drivers/scsi/atari_NCR5380.c | 135 +++++++++++++++++--------------------------
3 files changed, 109 insertions(+), 109 deletions(-)
Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h 2016-01-03 16:04:08.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h 2016-01-03 16:04:09.000000000 +1100
@@ -256,6 +256,7 @@ struct NCR5380_hostdata {
volatile struct scsi_cmnd *connected; /* currently connected command */
volatile struct scsi_cmnd *issue_queue; /* waiting to be issued */
volatile struct scsi_cmnd *disconnected_queue; /* waiting for reconnect */
+ spinlock_t lock; /* protects this struct */
int flags;
struct scsi_eh_save ses;
char info[256];
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c 2016-01-03 16:04:08.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c 2016-01-03 16:04:09.000000000 +1100
@@ -546,15 +546,13 @@ static struct {
static void NCR5380_print(struct Scsi_Host *instance)
{
unsigned char status, data, basr, mr, icr, i;
- unsigned long flags;
- local_irq_save(flags);
data = NCR5380_read(CURRENT_SCSI_DATA_REG);
status = NCR5380_read(STATUS_REG);
mr = NCR5380_read(MODE_REG);
icr = NCR5380_read(INITIATOR_COMMAND_REG);
basr = NCR5380_read(BUS_AND_STATUS_REG);
- local_irq_restore(flags);
+
printk("STATUS_REG: %02x ", status);
for (i = 0; signals[i].mask; ++i)
if (status & signals[i].mask)
@@ -684,14 +682,12 @@ static void __maybe_unused NCR5380_print
{
struct NCR5380_hostdata *hostdata;
struct scsi_cmnd *ptr;
- unsigned long flags;
NCR5380_dprint(NDEBUG_ANY, instance);
NCR5380_dprint_phase(NDEBUG_ANY, instance);
hostdata = (struct NCR5380_hostdata *)instance->hostdata;
- local_irq_save(flags);
if (!hostdata->connected)
printk("scsi%d: no currently connected command\n", HOSTNO);
else
@@ -704,8 +700,6 @@ static void __maybe_unused NCR5380_print
for (ptr = (struct scsi_cmnd *) hostdata->disconnected_queue; ptr;
ptr = NEXT(ptr))
lprint_Scsi_Cmnd(ptr);
-
- local_irq_restore(flags);
printk("\n");
}
@@ -732,7 +726,7 @@ static int __maybe_unused NCR5380_show_i
hostdata = (struct NCR5380_hostdata *)instance->hostdata;
- local_irq_save(flags);
+ spin_lock_irqsave(&hostdata->lock, flags);
if (!hostdata->connected)
seq_printf(m, "scsi%d: no currently connected command\n", HOSTNO);
else
@@ -746,7 +740,7 @@ static int __maybe_unused NCR5380_show_i
ptr = NEXT(ptr))
show_Scsi_Cmnd(ptr, m);
- local_irq_restore(flags);
+ spin_unlock_irqrestore(&hostdata->lock, flags);
return 0;
}
@@ -784,6 +778,7 @@ static int __init NCR5380_init(struct Sc
#if defined (REAL_DMA)
hostdata->dma_len = 0;
#endif
+ spin_lock_init(&hostdata->lock);
hostdata->connected = NULL;
hostdata->issue_queue = NULL;
hostdata->disconnected_queue = NULL;
@@ -946,7 +941,7 @@ static int NCR5380_queue_command(struct
if (!NCR5380_acquire_dma_irq(instance))
return SCSI_MLQUEUE_HOST_BUSY;
- local_irq_save(flags);
+ spin_lock_irqsave(&hostdata->lock, flags);
/*
* Insert the cmd into the issue queue. Note that REQUEST SENSE
@@ -966,7 +961,7 @@ static int NCR5380_queue_command(struct
LIST(cmd, tmp);
SET_NEXT(tmp, cmd);
}
- local_irq_restore(flags);
+ spin_unlock_irqrestore(&hostdata->lock, flags);
dprintk(NDEBUG_QUEUES, "scsi%d: command added to %s of queue\n", H_NO(cmd),
(cmd->cmnd[0] == REQUEST_SENSE) ? "head" : "tail");
@@ -1006,7 +1001,6 @@ static void NCR5380_main(struct work_str
struct Scsi_Host *instance = hostdata->host;
struct scsi_cmnd *tmp, *prev;
int done;
- unsigned long flags;
/*
* ++roman: Just disabling the NCR interrupt isn't sufficient here,
@@ -1014,9 +1008,8 @@ static void NCR5380_main(struct work_str
* alter queues and touch the Falcon lock.
*/
- local_save_flags(flags);
+ spin_lock_irq(&hostdata->lock);
do {
- local_irq_disable(); /* Freeze request queues */
done = 1;
if (!hostdata->connected) {
@@ -1043,7 +1036,6 @@ static void NCR5380_main(struct work_str
tmp, scmd_id(tmp), hostdata->busy[scmd_id(tmp)],
lun);
/* When we find one, remove it from the issue queue. */
- /* ++guenther: possible race with Falcon locking */
if (
#ifdef SUPPORT_TAGS
!is_lun_busy( tmp, tmp->cmnd[0] != REQUEST_SENSE)
@@ -1051,8 +1043,6 @@ static void NCR5380_main(struct work_str
!(hostdata->busy[tmp->device->id] & (1 << lun))
#endif
) {
- /* ++guenther: just to be sure, this must be atomic */
- local_irq_disable();
if (prev) {
REMOVE(prev, NEXT(prev), tmp, NEXT(tmp));
SET_NEXT(prev, NEXT(tmp));
@@ -1063,9 +1053,6 @@ static void NCR5380_main(struct work_str
SET_NEXT(tmp, NULL);
hostdata->retain_dma_intr++;
- /* reenable interrupts after finding one */
- local_irq_restore(flags);
-
/*
* Attempt to establish an I_T_L nexus here.
* On success, instance->hostdata->connected is set.
@@ -1090,13 +1077,10 @@ static void NCR5380_main(struct work_str
#endif
if (!NCR5380_select(instance, tmp)) {
/* OK or bad target */
- local_irq_disable();
hostdata->retain_dma_intr--;
maybe_release_dma_irq(instance);
- local_irq_restore(flags);
} else {
/* Need to retry */
- local_irq_disable();
LIST(tmp, hostdata->issue_queue);
SET_NEXT(tmp, hostdata->issue_queue);
hostdata->issue_queue = tmp;
@@ -1104,7 +1088,6 @@ static void NCR5380_main(struct work_str
cmd_free_tag(tmp);
#endif
hostdata->retain_dma_intr--;
- local_irq_restore(flags);
done = 0;
dprintk(NDEBUG_MAIN, "scsi%d: main(): select() failed, "
"returned to issue_queue\n", HOSTNO);
@@ -1120,7 +1103,6 @@ static void NCR5380_main(struct work_str
&& !hostdata->dma_len
#endif
) {
- local_irq_restore(flags);
dprintk(NDEBUG_MAIN, "scsi%d: main: performing information transfer\n",
HOSTNO);
NCR5380_information_transfer(instance);
@@ -1128,7 +1110,7 @@ static void NCR5380_main(struct work_str
done = 0;
}
} while (!done);
- local_irq_restore(flags);
+ spin_unlock_irq(&hostdata->lock);
}
@@ -1257,6 +1239,9 @@ static irqreturn_t NCR5380_intr(int irq,
struct NCR5380_hostdata *hostdata = shost_priv(instance);
int handled = 0;
unsigned char basr;
+ unsigned long flags;
+
+ spin_lock_irqsave(&hostdata->lock, flags);
basr = NCR5380_read(BUS_AND_STATUS_REG);
if (basr & BASR_IRQ) {
@@ -1316,6 +1301,8 @@ static irqreturn_t NCR5380_intr(int irq,
#endif
}
+ spin_unlock_irqrestore(&hostdata->lock, flags);
+
return IRQ_RETVAL(handled);
}
@@ -1355,7 +1342,6 @@ static int NCR5380_select(struct Scsi_Ho
unsigned char *data;
int len;
int err;
- unsigned long flags;
NCR5380_dprint(NDEBUG_ARBITRATION, instance);
dprintk(NDEBUG_ARBITRATION, "scsi%d: starting arbitration, id = %d\n", HOSTNO,
@@ -1366,11 +1352,6 @@ static int NCR5380_select(struct Scsi_Ho
* data bus during SELECTION.
*/
- local_irq_save(flags);
- if (hostdata->connected) {
- local_irq_restore(flags);
- return -1;
- }
NCR5380_write(TARGET_COMMAND_REG, 0);
/*
@@ -1384,10 +1365,11 @@ static int NCR5380_select(struct Scsi_Ho
* Bus Free Delay, arbitration will begin.
*/
- local_irq_restore(flags);
+ spin_unlock_irq(&hostdata->lock);
err = NCR5380_poll_politely2(instance, MODE_REG, MR_ARBITRATE, 0,
INITIATOR_COMMAND_REG, ICR_ARBITRATION_PROGRESS,
ICR_ARBITRATION_PROGRESS, HZ);
+ spin_lock_irq(&hostdata->lock);
if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE)) {
/* Reselection interrupt */
return -1;
@@ -1398,6 +1380,7 @@ static int NCR5380_select(struct Scsi_Ho
"select: arbitration timeout\n");
return -1;
}
+ spin_unlock_irq(&hostdata->lock);
/* The SCSI-2 arbitration delay is 2.4 us */
udelay(3);
@@ -1405,11 +1388,11 @@ static int NCR5380_select(struct Scsi_Ho
/* Check for lost arbitration */
if ((NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) ||
(NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_higher_mask) ||
- (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) ||
- hostdata->connected) {
+ (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST)) {
NCR5380_write(MODE_REG, MR_BASE);
dprintk(NDEBUG_ARBITRATION, "scsi%d: lost arbitration, deasserting MR_ARBITRATE\n",
HOSTNO);
+ spin_lock_irq(&hostdata->lock);
return -1;
}
@@ -1430,6 +1413,8 @@ static int NCR5380_select(struct Scsi_Ho
else
udelay(2);
+ spin_lock_irq(&hostdata->lock);
+
/* NCR5380_reselect() clears MODE_REG after a reselection interrupt */
if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE))
return -1;
@@ -1457,14 +1442,10 @@ static int NCR5380_select(struct Scsi_Ho
* Reselect interrupts must be turned off prior to the dropping of BSY,
* otherwise we will trigger an interrupt.
*/
-
- if (hostdata->connected) {
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
- return -1;
- }
-
NCR5380_write(SELECT_ENABLE_REG, 0);
+ spin_unlock_irq(&hostdata->lock);
+
/*
* The initiator shall then wait at least two deskew delays and release
* the BSY signal.
@@ -1505,6 +1486,7 @@ static int NCR5380_select(struct Scsi_Ho
msecs_to_jiffies(250));
if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) == (SR_SEL | SR_IO)) {
+ spin_lock_irq(&hostdata->lock);
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
NCR5380_reselect(instance);
if (!hostdata->connected)
@@ -1515,6 +1497,7 @@ static int NCR5380_select(struct Scsi_Ho
}
if (err < 0) {
+ spin_lock_irq(&hostdata->lock);
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
cmd->result = DID_BAD_TARGET << 16;
#ifdef SUPPORT_TAGS
@@ -1554,6 +1537,7 @@ static int NCR5380_select(struct Scsi_Ho
/* Wait for start of REQ/ACK handshake */
err = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ);
+ spin_lock_irq(&hostdata->lock);
if (err < 0) {
shost_printk(KERN_ERR, instance, "select: REQ timeout\n");
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
@@ -1583,6 +1567,7 @@ static int NCR5380_select(struct Scsi_Ho
NCR5380_transfer_pio(instance, &phase, &len, &data);
dprintk(NDEBUG_SELECTION, "scsi%d: nexus established.\n", HOSTNO);
/* XXX need to handle errors here */
+
hostdata->connected = cmd;
#ifndef SUPPORT_TAGS
hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);
@@ -1849,7 +1834,6 @@ static int NCR5380_transfer_dma(struct S
SETUP_HOSTDATA(instance);
register int c = *count;
register unsigned char p = *phase;
- unsigned long flags;
#if defined(CONFIG_SUN3)
/* sanity check */
@@ -1865,7 +1849,6 @@ static int NCR5380_transfer_dma(struct S
c, (p & SR_IO) ? "to" : "from", *data);
/* netbsd turns off ints here, why not be safe and do it too */
- local_irq_save(flags);
/* send start chain */
sun3scsi_dma_start(c, *data);
@@ -1885,8 +1868,6 @@ static int NCR5380_transfer_dma(struct S
dregs->csr |= CSR_DMA_ENABLE;
#endif
- local_irq_restore(flags);
-
sun3_dma_active = 1;
#else /* !defined(CONFIG_SUN3) */
@@ -1913,11 +1894,9 @@ static int NCR5380_transfer_dma(struct S
/* On the Medusa, it is a must to initialize the DMA before
* starting the NCR. This is also the cleaner way for the TT.
*/
- local_irq_save(flags);
hostdata->dma_len = (p & SR_IO) ?
NCR5380_dma_read_setup(instance, d, c) :
NCR5380_dma_write_setup(instance, d, c);
- local_irq_restore(flags);
}
if (p & SR_IO)
@@ -1931,11 +1910,9 @@ static int NCR5380_transfer_dma(struct S
/* On the Falcon, the DMA setup must be done after the last */
/* NCR access, else the DMA setup gets trashed!
*/
- local_irq_save(flags);
hostdata->dma_len = (p & SR_IO) ?
NCR5380_dma_read_setup(instance, d, c) :
NCR5380_dma_write_setup(instance, d, c);
- local_irq_restore(flags);
}
#endif /* !defined(CONFIG_SUN3) */
@@ -1963,7 +1940,6 @@ static int NCR5380_transfer_dma(struct S
static void NCR5380_information_transfer(struct Scsi_Host *instance)
{
SETUP_HOSTDATA(instance);
- unsigned long flags;
unsigned char msgout = NOP;
int sink = 0;
int len;
@@ -1972,13 +1948,13 @@ static void NCR5380_information_transfer
#endif
unsigned char *data;
unsigned char phase, tmp, extended_msg[10], old_phase = 0xff;
- struct scsi_cmnd *cmd = (struct scsi_cmnd *) hostdata->connected;
+ struct scsi_cmnd *cmd;
#ifdef SUN3_SCSI_VME
dregs->csr |= CSR_INTR;
#endif
- while (1) {
+ while ((cmd = hostdata->connected)) {
tmp = NCR5380_read(STATUS_REG);
/* We only have a valid SCSI phase when REQ is asserted */
if (tmp & SR_REQ) {
@@ -2112,9 +2088,13 @@ static void NCR5380_information_transfer
}
} else
#endif /* defined(REAL_DMA) */
+ {
+ spin_unlock_irq(&hostdata->lock);
NCR5380_transfer_pio(instance, &phase,
(int *)&cmd->SCp.this_residual,
(unsigned char **)&cmd->SCp.ptr);
+ spin_lock_irq(&hostdata->lock);
+ }
#if defined(CONFIG_SUN3) && defined(REAL_DMA)
/* if we had intended to dma that command clear it */
if (sun3_dma_setup_done == cmd)
@@ -2124,7 +2104,6 @@ static void NCR5380_information_transfer
case PHASE_MSGIN:
len = 1;
data = &tmp;
- NCR5380_write(SELECT_ENABLE_REG, 0); /* disable reselects */
NCR5380_transfer_pio(instance, &phase, &len, &data);
cmd->SCp.Message = tmp;
@@ -2136,7 +2115,6 @@ static void NCR5380_information_transfer
dprintk(NDEBUG_QUEUES, "scsi%d: command for target %d, lun %llu "
"completed\n", HOSTNO, cmd->device->id, cmd->device->lun);
- local_irq_save(flags);
hostdata->connected = NULL;
#ifdef SUPPORT_TAGS
cmd_free_tag(cmd);
@@ -2152,8 +2130,6 @@ static void NCR5380_information_transfer
#else
hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
#endif
- /* Enable reselect interrupts */
- NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
/*
* I'm not sure what the correct thing to do here is :
@@ -2211,13 +2187,10 @@ static void NCR5380_information_transfer
* disconnected queue.
*/
maybe_release_dma_irq(instance);
- local_irq_restore(flags);
return;
case MESSAGE_REJECT:
/* Accept message by clearing ACK */
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
- /* Enable reselect interrupts */
- NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
switch (hostdata->last_message) {
case HEAD_OF_QUEUE_TAG:
case ORDERED_QUEUE_TAG:
@@ -2241,12 +2214,10 @@ static void NCR5380_information_transfer
case DISCONNECT:
/* Accept message by clearing ACK */
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
- local_irq_save(flags);
LIST(cmd,hostdata->disconnected_queue);
SET_NEXT(cmd, hostdata->disconnected_queue);
hostdata->connected = NULL;
hostdata->disconnected_queue = cmd;
- local_irq_restore(flags);
dprintk(NDEBUG_QUEUES, "scsi%d: command for target %d lun %llu was "
"moved from connected to the "
"disconnected_queue\n", HOSTNO,
@@ -2277,8 +2248,6 @@ static void NCR5380_information_transfer
case RESTORE_POINTERS:
/* Accept message by clearing ACK */
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
- /* Enable reselect interrupts */
- NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
break;
case EXTENDED_MESSAGE:
/*
@@ -2297,6 +2266,8 @@ static void NCR5380_information_transfer
/* Accept first byte by clearing ACK */
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+ spin_unlock_irq(&hostdata->lock);
+
dprintk(NDEBUG_EXTENDED, "scsi%d: receiving extended message\n", HOSTNO);
len = 2;
@@ -2335,6 +2306,11 @@ static void NCR5380_information_transfer
HOSTNO, extended_msg[2], extended_msg[1]);
tmp = 0;
}
+
+ spin_lock_irq(&hostdata->lock);
+ if (!hostdata->connected)
+ return;
+
/* Fall through to reject message */
/*
@@ -2367,7 +2343,6 @@ static void NCR5380_information_transfer
hostdata->last_message = msgout;
NCR5380_transfer_pio(instance, &phase, &len, &data);
if (msgout == ABORT) {
- local_irq_save(flags);
#ifdef SUPPORT_TAGS
cmd_free_tag(cmd);
#else
@@ -2376,7 +2351,6 @@ static void NCR5380_information_transfer
hostdata->connected = NULL;
cmd->result = DID_ERROR << 16;
maybe_release_dma_irq(instance);
- local_irq_restore(flags);
cmd->scsi_done(cmd);
NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
return;
@@ -2404,9 +2378,11 @@ static void NCR5380_information_transfer
NCR5380_dprint(NDEBUG_ANY, instance);
} /* switch(phase) */
} else {
+ spin_unlock_irq(&hostdata->lock);
NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ);
+ spin_lock_irq(&hostdata->lock);
}
- } /* while (1) */
+ }
}
/*
@@ -2639,9 +2615,9 @@ int NCR5380_abort(struct scsi_cmnd *cmd)
scmd_printk(KERN_NOTICE, cmd, "aborting command\n");
- NCR5380_print_status(instance);
+ spin_lock_irqsave(&hostdata->lock, flags);
- local_irq_save(flags);
+ NCR5380_print_status(instance);
dprintk(NDEBUG_ABORT, "scsi%d: abort called basr 0x%02x, sr 0x%02x\n", HOSTNO,
NCR5380_read(BUS_AND_STATUS_REG),
@@ -2683,11 +2659,11 @@ int NCR5380_abort(struct scsi_cmnd *cmd)
hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
#endif
maybe_release_dma_irq(instance);
- local_irq_restore(flags);
+ spin_unlock_irqrestore(&hostdata->lock, flags);
cmd->scsi_done(cmd);
return SUCCESS;
} else {
- local_irq_restore(flags);
+ spin_unlock_irqrestore(&hostdata->lock, flags);
printk("scsi%d: abort of connected command failed!\n", HOSTNO);
return FAILED;
}
@@ -2707,7 +2683,7 @@ int NCR5380_abort(struct scsi_cmnd *cmd)
SET_NEXT(tmp, NULL);
tmp->result = DID_ABORT << 16;
maybe_release_dma_irq(instance);
- local_irq_restore(flags);
+ spin_unlock_irqrestore(&hostdata->lock, flags);
dprintk(NDEBUG_ABORT, "scsi%d: abort removed command from issue queue.\n",
HOSTNO);
/* Tagged queuing note: no tag to free here, hasn't been assigned
@@ -2729,7 +2705,7 @@ int NCR5380_abort(struct scsi_cmnd *cmd)
*/
if (hostdata->connected) {
- local_irq_restore(flags);
+ spin_unlock_irqrestore(&hostdata->lock, flags);
dprintk(NDEBUG_ABORT, "scsi%d: abort failed, command connected.\n", HOSTNO);
return FAILED;
}
@@ -2762,17 +2738,16 @@ int NCR5380_abort(struct scsi_cmnd *cmd)
for (tmp = (struct scsi_cmnd *) hostdata->disconnected_queue; tmp;
tmp = NEXT(tmp)) {
if (cmd == tmp) {
- local_irq_restore(flags);
dprintk(NDEBUG_ABORT, "scsi%d: aborting disconnected command.\n", HOSTNO);
- if (NCR5380_select(instance, cmd))
+ if (NCR5380_select(instance, cmd)) {
+ spin_unlock_irq(&hostdata->lock);
return FAILED;
-
+ }
dprintk(NDEBUG_ABORT, "scsi%d: nexus reestablished.\n", HOSTNO);
do_abort(instance);
- local_irq_save(flags);
for (prev = (struct scsi_cmnd **)&(hostdata->disconnected_queue),
tmp = (struct scsi_cmnd *)hostdata->disconnected_queue;
tmp; prev = NEXTADDR(tmp), tmp = NEXT(tmp)) {
@@ -2791,7 +2766,7 @@ int NCR5380_abort(struct scsi_cmnd *cmd)
hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
#endif
maybe_release_dma_irq(instance);
- local_irq_restore(flags);
+ spin_unlock_irqrestore(&hostdata->lock, flags);
tmp->scsi_done(tmp);
return SUCCESS;
}
@@ -2804,7 +2779,7 @@ int NCR5380_abort(struct scsi_cmnd *cmd)
* released after the abort, in case it is kept due to some bug.
*/
maybe_release_dma_irq(instance);
- local_irq_restore(flags);
+ spin_unlock_irqrestore(&hostdata->lock, flags);
/*
* Case 5 : If we reached this point, the command was not found in any of
@@ -2836,7 +2811,7 @@ static int NCR5380_bus_reset(struct scsi
int i;
unsigned long flags;
- local_irq_save(flags);
+ spin_lock_irqsave(&hostdata->lock, flags);
#if (NDEBUG & NDEBUG_ANY)
scmd_printk(KERN_INFO, cmd, "performing bus reset\n");
@@ -2876,7 +2851,7 @@ static int NCR5380_bus_reset(struct scsi
#endif
maybe_release_dma_irq(instance);
- local_irq_restore(flags);
+ spin_unlock_irqrestore(&hostdata->lock, flags);
return SUCCESS;
}
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c 2016-01-03 16:04:08.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c 2016-01-03 16:04:09.000000000 +1100
@@ -612,6 +612,7 @@ static int __maybe_unused NCR5380_show_i
{
struct NCR5380_hostdata *hostdata;
struct scsi_cmnd *ptr;
+ unsigned long flags;
hostdata = (struct NCR5380_hostdata *) instance->hostdata;
@@ -619,7 +620,7 @@ static int __maybe_unused NCR5380_show_i
seq_printf(m, "Highwater I/O busy spin counts: write %d, read %d\n",
hostdata->spin_max_w, hostdata->spin_max_r);
#endif
- spin_lock_irq(instance->host_lock);
+ spin_lock_irqsave(&hostdata->lock, flags);
if (!hostdata->connected)
seq_printf(m, "scsi%d: no currently connected command\n", instance->host_no);
else
@@ -631,7 +632,7 @@ static int __maybe_unused NCR5380_show_i
seq_printf(m, "scsi%d: disconnected_queue\n", instance->host_no);
for (ptr = (struct scsi_cmnd *) hostdata->disconnected_queue; ptr; ptr = (struct scsi_cmnd *) ptr->host_scribble)
lprint_Scsi_Cmnd(ptr, m);
- spin_unlock_irq(instance->host_lock);
+ spin_unlock_irqrestore(&hostdata->lock, flags);
return 0;
}
@@ -691,6 +692,7 @@ static int NCR5380_init(struct Scsi_Host
#ifdef REAL_DMA
hostdata->dmalen = 0;
#endif
+ spin_lock_init(&hostdata->lock);
hostdata->connected = NULL;
hostdata->issue_queue = NULL;
hostdata->disconnected_queue = NULL;
@@ -830,7 +832,7 @@ static int NCR5380_queue_command(struct
cmd->host_scribble = NULL;
cmd->result = 0;
- spin_lock_irqsave(instance->host_lock, flags);
+ spin_lock_irqsave(&hostdata->lock, flags);
/*
* Insert the cmd into the issue queue. Note that REQUEST SENSE
@@ -848,7 +850,7 @@ static int NCR5380_queue_command(struct
LIST(cmd, tmp);
tmp->host_scribble = (unsigned char *) cmd;
}
- spin_unlock_irqrestore(instance->host_lock, flags);
+ spin_unlock_irqrestore(&hostdata->lock, flags);
dprintk(NDEBUG_QUEUES, "scsi%d : command added to %s of queue\n", instance->host_no, (cmd->cmnd[0] == REQUEST_SENSE) ? "head" : "tail");
@@ -877,10 +879,10 @@ static void NCR5380_main(struct work_str
struct scsi_cmnd *tmp, *prev;
int done;
- spin_lock_irq(instance->host_lock);
+ spin_lock_irq(&hostdata->lock);
do {
- /* Lock held here */
done = 1;
+
if (!hostdata->connected) {
dprintk(NDEBUG_MAIN, "scsi%d : not connected\n", instance->host_no);
/*
@@ -930,11 +932,10 @@ static void NCR5380_main(struct work_str
}
if (hostdata->connected)
break;
- /* lock held here still */
} /* if target/lun is not busy */
} /* for */
- /* exited locked */
} /* if (!hostdata->connected) */
+
if (hostdata->connected
#ifdef REAL_DMA
&& !hostdata->dmalen
@@ -946,8 +947,7 @@ static void NCR5380_main(struct work_str
done = 0;
}
} while (!done);
-
- spin_unlock_irq(instance->host_lock);
+ spin_unlock_irq(&hostdata->lock);
}
#ifndef DONT_USE_INTR
@@ -994,7 +994,7 @@ static irqreturn_t NCR5380_intr(int irq,
unsigned char basr;
unsigned long flags;
- spin_lock_irqsave(instance->host_lock, flags);
+ spin_lock_irqsave(&hostdata->lock, flags);
basr = NCR5380_read(BUS_AND_STATUS_REG);
if (basr & BASR_IRQ) {
@@ -1058,7 +1058,7 @@ static irqreturn_t NCR5380_intr(int irq,
shost_printk(KERN_NOTICE, instance, "interrupt without IRQ bit\n");
}
- spin_unlock_irqrestore(instance->host_lock, flags);
+ spin_unlock_irqrestore(&hostdata->lock, flags);
return IRQ_RETVAL(handled);
}
@@ -1125,11 +1125,11 @@ static int NCR5380_select(struct Scsi_Ho
* Bus Free Delay, arbitration will begin.
*/
- spin_unlock_irq(instance->host_lock);
+ spin_unlock_irq(&hostdata->lock);
err = NCR5380_poll_politely2(instance, MODE_REG, MR_ARBITRATE, 0,
INITIATOR_COMMAND_REG, ICR_ARBITRATION_PROGRESS,
ICR_ARBITRATION_PROGRESS, HZ);
- spin_lock_irq(instance->host_lock);
+ spin_lock_irq(&hostdata->lock);
if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE)) {
/* Reselection interrupt */
return -1;
@@ -1140,6 +1140,7 @@ static int NCR5380_select(struct Scsi_Ho
"select: arbitration timeout\n");
return -1;
}
+ spin_unlock_irq(&hostdata->lock);
/* The SCSI-2 arbitration delay is 2.4 us */
udelay(3);
@@ -1148,6 +1149,7 @@ static int NCR5380_select(struct Scsi_Ho
if ((NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) || (NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_higher_mask) || (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST)) {
NCR5380_write(MODE_REG, MR_BASE);
dprintk(NDEBUG_ARBITRATION, "scsi%d : lost arbitration, deasserting MR_ARBITRATE\n", instance->host_no);
+ spin_lock_irq(&hostdata->lock);
return -1;
}
@@ -1168,6 +1170,8 @@ static int NCR5380_select(struct Scsi_Ho
else
udelay(2);
+ spin_lock_irq(&hostdata->lock);
+
/* NCR5380_reselect() clears MODE_REG after a reselection interrupt */
if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE))
return -1;
@@ -1196,6 +1200,8 @@ static int NCR5380_select(struct Scsi_Ho
*/
NCR5380_write(SELECT_ENABLE_REG, 0);
+ spin_unlock_irq(&hostdata->lock);
+
/*
* The initiator shall then wait at least two deskew delays and release
* the BSY signal.
@@ -1235,6 +1241,7 @@ static int NCR5380_select(struct Scsi_Ho
msecs_to_jiffies(250));
if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) == (SR_SEL | SR_IO)) {
+ spin_lock_irq(&hostdata->lock);
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
NCR5380_reselect(instance);
if (!hostdata->connected)
@@ -1244,6 +1251,7 @@ static int NCR5380_select(struct Scsi_Ho
}
if (err < 0) {
+ spin_lock_irq(&hostdata->lock);
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
cmd->result = DID_BAD_TARGET << 16;
cmd->scsi_done(cmd);
@@ -1280,9 +1288,8 @@ static int NCR5380_select(struct Scsi_Ho
/* Wait for start of REQ/ACK handshake */
- spin_unlock_irq(instance->host_lock);
err = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ);
- spin_lock_irq(instance->host_lock);
+ spin_lock_irq(&hostdata->lock);
if (err < 0) {
shost_printk(KERN_ERR, instance, "select: REQ timeout\n");
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
@@ -1302,6 +1309,7 @@ static int NCR5380_select(struct Scsi_Ho
NCR5380_transfer_pio(instance, &phase, &len, &data);
dprintk(NDEBUG_SELECTION, "scsi%d : nexus established.\n", instance->host_no);
/* XXX need to handle errors here */
+
hostdata->connected = cmd;
hostdata->busy[cmd->device->id] |= (1 << (cmd->device->lun & 0xFF));
@@ -1805,9 +1813,9 @@ static void NCR5380_information_transfer
#endif
unsigned char *data;
unsigned char phase, tmp, extended_msg[10], old_phase = 0xff;
- struct scsi_cmnd *cmd = (struct scsi_cmnd *) hostdata->connected;
+ struct scsi_cmnd *cmd;
- while (1) {
+ while ((cmd = hostdata->connected)) {
tmp = NCR5380_read(STATUS_REG);
/* We only have a valid SCSI phase when REQ is asserted */
if (tmp & SR_REQ) {
@@ -1883,8 +1891,12 @@ static void NCR5380_information_transfer
cmd->SCp.this_residual -= transfersize - len;
} else
#endif /* defined(PSEUDO_DMA) || defined(REAL_DMA_POLL) */
+ {
+ spin_unlock_irq(&hostdata->lock);
NCR5380_transfer_pio(instance, &phase, (int *) &cmd->SCp.this_residual, (unsigned char **)
&cmd->SCp.ptr);
+ spin_lock_irq(&hostdata->lock);
+ }
break;
case PHASE_MSGIN:
len = 1;
@@ -2016,6 +2028,9 @@ static void NCR5380_information_transfer
extended_msg[0] = EXTENDED_MESSAGE;
/* Accept first byte by clearing ACK */
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+
+ spin_unlock_irq(&hostdata->lock);
+
dprintk(NDEBUG_EXTENDED, "scsi%d : receiving extended message\n", instance->host_no);
len = 2;
@@ -2050,6 +2065,11 @@ static void NCR5380_information_transfer
printk("scsi%d: extended message code %02x length %d is too long\n", instance->host_no, extended_msg[2], extended_msg[1]);
tmp = 0;
}
+
+ spin_lock_irq(&hostdata->lock);
+ if (!hostdata->connected)
+ return;
+
/* Fall through to reject message */
/*
@@ -2109,11 +2129,11 @@ static void NCR5380_information_transfer
NCR5380_dprint(NDEBUG_ANY, instance);
} /* switch(phase) */
} else {
- spin_unlock_irq(instance->host_lock);
+ spin_unlock_irq(&hostdata->lock);
NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, HZ);
- spin_lock_irq(instance->host_lock);
+ spin_lock_irq(&hostdata->lock);
}
- } /* while (1) */
+ }
}
/*
@@ -2309,10 +2329,12 @@ static int NCR5380_abort(struct scsi_cmn
struct Scsi_Host *instance = cmd->device->host;
struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
struct scsi_cmnd *tmp, **prev;
+ unsigned long flags;
scmd_printk(KERN_WARNING, cmd, "aborting command\n");
- spin_lock_irq(instance->host_lock);
+ spin_lock_irqsave(&hostdata->lock, flags);
+
NCR5380_print_status(instance);
dprintk(NDEBUG_ABORT, "scsi%d : abort called\n", instance->host_no);
@@ -2359,7 +2381,7 @@ static int NCR5380_abort(struct scsi_cmn
REMOVE(5, *prev, tmp, tmp->host_scribble);
(*prev) = (struct scsi_cmnd *) tmp->host_scribble;
tmp->host_scribble = NULL;
- spin_unlock_irq(instance->host_lock);
+ spin_unlock_irqrestore(&hostdata->lock, flags);
tmp->result = DID_ABORT << 16;
dprintk(NDEBUG_ABORT, "scsi%d : abort removed command from issue queue.\n", instance->host_no);
tmp->scsi_done(tmp);
@@ -2383,7 +2405,7 @@ static int NCR5380_abort(struct scsi_cmn
*/
if (hostdata->connected) {
- spin_unlock_irq(instance->host_lock);
+ spin_unlock_irqrestore(&hostdata->lock, flags);
dprintk(NDEBUG_ABORT, "scsi%d : abort failed, command connected.\n", instance->host_no);
return FAILED;
}
@@ -2417,7 +2439,7 @@ static int NCR5380_abort(struct scsi_cmn
dprintk(NDEBUG_ABORT, "scsi%d : aborting disconnected command.\n", instance->host_no);
if (NCR5380_select(instance, cmd)) {
- spin_unlock_irq(instance->host_lock);
+ spin_unlock_irq(&hostdata->lock);
return FAILED;
}
dprintk(NDEBUG_ABORT, "scsi%d : nexus reestablished.\n", instance->host_no);
@@ -2429,7 +2451,7 @@ static int NCR5380_abort(struct scsi_cmn
REMOVE(5, *prev, tmp, tmp->host_scribble);
*prev = (struct scsi_cmnd *) tmp->host_scribble;
tmp->host_scribble = NULL;
- spin_unlock_irq(instance->host_lock);
+ spin_unlock_irqrestore(&hostdata->lock, flags);
tmp->result = DID_ABORT << 16;
tmp->scsi_done(tmp);
return SUCCESS;
@@ -2444,7 +2466,7 @@ static int NCR5380_abort(struct scsi_cmn
* so we won't panic, but we will notify the user in case something really
* broke.
*/
- spin_unlock_irq(instance->host_lock);
+ spin_unlock_irqrestore(&hostdata->lock, flags);
printk(KERN_WARNING "scsi%d : warning : SCSI command probably completed successfully\n"
" before abortion\n", instance->host_no);
return FAILED;
@@ -2461,8 +2483,10 @@ static int NCR5380_abort(struct scsi_cmn
static int NCR5380_bus_reset(struct scsi_cmnd *cmd)
{
struct Scsi_Host *instance = cmd->device->host;
+ struct NCR5380_hostdata *hostdata = shost_priv(instance);
+ unsigned long flags;
- spin_lock_irq(instance->host_lock);
+ spin_lock_irqsave(&hostdata->lock, flags);
#if (NDEBUG & NDEBUG_ANY)
scmd_printk(KERN_INFO, cmd, "performing bus reset\n");
@@ -2471,7 +2495,7 @@ static int NCR5380_bus_reset(struct scsi
do_reset(instance);
- spin_unlock_irq(instance->host_lock);
+ spin_unlock_irqrestore(&hostdata->lock, flags);
return SUCCESS;
}
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Finn Thain <fthain@telegraphics.com.au> |
|---|---|
| Date | 2016-01-03 06:40 +0100 |
| Subject | [PATCH v4 22/78] ncr5380: Eliminate selecting state |
| Message-ID | <qMJyy-1gX-9@gated-at.bofh.it> |
| In reply to | #1300181 |
Linux v2.1.105 changed the algorithm for polling for the BSY signal
in NCR5380_select() and NCR5380_main().
Presently, this code has a bug. Back then, NCR5380_set_timer(hostdata, 1)
meant reschedule main() after sleeping for 10 ms. Repeated 25 times this
provided the recommended 250 ms selection time-out delay. This got broken
when HZ became configurable.
We could fix this but there's no need to reschedule the main loop. This
BSY polling presently happens when the NCR5380_main() work queue item
calls NCR5380_select(), which in turn schedules NCR5380_main(), which
calls NCR5380_select() again, and so on.
This algorithm is a deviation from the simpler one in atari_NCR5380.c.
The extra complexity and state is pointless. There's no reason to
stop selection half-way and return to to the main loop when the main
loop can do nothing useful until selection completes.
So just poll for BSY. We can sleep while polling now that we have a
suitable workqueue.
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Tested-by: Ondrej Zary <linux@rainbow-software.org>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
---
drivers/scsi/NCR5380.c | 74 ++++++++-----------------------------------
drivers/scsi/NCR5380.h | 2 -
drivers/scsi/atari_NCR5380.c | 49 ++++++++--------------------
3 files changed, 29 insertions(+), 96 deletions(-)
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c 2016-01-03 16:03:26.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c 2016-01-03 16:03:28.000000000 +1100
@@ -988,7 +988,7 @@ static void NCR5380_main(struct work_str
do {
/* Lock held here */
done = 1;
- if (!hostdata->connected && !hostdata->selecting) {
+ if (!hostdata->connected) {
dprintk(NDEBUG_MAIN, "scsi%d : not connected\n", instance->host_no);
/*
* Search through the issue_queue for a command destined
@@ -1018,9 +1018,6 @@ static void NCR5380_main(struct work_str
*/
dprintk(NDEBUG_MAIN|NDEBUG_QUEUES, "scsi%d : main() : command for target %d lun %llu removed from issue_queue\n", instance->host_no, tmp->device->id, tmp->device->lun);
- hostdata->selecting = NULL;
- /* RvC: have to preset this to indicate a new command is being performed */
-
/*
* REQUEST SENSE commands are issued without tagged
* queueing, even on SCSI-II devices because the
@@ -1038,26 +1035,13 @@ static void NCR5380_main(struct work_str
done = 0;
dprintk(NDEBUG_MAIN|NDEBUG_QUEUES, "scsi%d : main(): select() failed, returned to issue_queue\n", instance->host_no);
}
- if (hostdata->connected ||
- hostdata->selecting)
+ if (hostdata->connected)
break;
/* lock held here still */
} /* if target/lun is not busy */
} /* for */
/* exited locked */
} /* if (!hostdata->connected) */
- if (hostdata->selecting) {
- tmp = (struct scsi_cmnd *) hostdata->selecting;
- /* Selection will drop and retake the lock */
- if (!NCR5380_select(instance, tmp)) {
- /* OK or bad target */
- } else {
- LIST(tmp, hostdata->issue_queue);
- tmp->host_scribble = (unsigned char *) hostdata->issue_queue;
- hostdata->issue_queue = tmp;
- done = 0;
- }
- } /* if hostdata->selecting */
if (hostdata->connected
#ifdef REAL_DMA
&& !hostdata->dmalen
@@ -1176,7 +1160,6 @@ static irqreturn_t NCR5380_intr(int dumm
* Returns : -1 if selection failed but should be retried.
* 0 if selection failed and should not be retried.
* 0 if selection succeeded completely (hostdata->connected == cmd).
- * 0 if selection in progress (hostdata->selecting == cmd).
*
* Side effects :
* If bus busy, arbitration failed, etc, NCR5380_select() will exit
@@ -1200,13 +1183,8 @@ static int NCR5380_select(struct Scsi_Ho
unsigned char tmp[3], phase;
unsigned char *data;
int len;
- unsigned long timeout;
- unsigned char value;
int err;
- if (hostdata->selecting)
- goto part2;
-
NCR5380_dprint(NDEBUG_ARBITRATION, instance);
dprintk(NDEBUG_ARBITRATION, "scsi%d : starting arbitration, id = %d\n", instance->host_no, instance->this_id);
@@ -1342,33 +1320,9 @@ static int NCR5380_select(struct Scsi_Ho
* selection.
*/
- timeout = jiffies + msecs_to_jiffies(250);
-
- /*
- * XXX very interesting - we're seeing a bounce where the BSY we
- * asserted is being reflected / still asserted (propagation delay?)
- * and it's detecting as true. Sigh.
- */
-
- hostdata->select_time = 0; /* we count the clock ticks at which we polled */
- hostdata->selecting = cmd;
-
-part2:
- /* RvC: here we enter after a sleeping period, or immediately after
- execution of part 1
- we poll only once ech clock tick */
- value = NCR5380_read(STATUS_REG) & (SR_BSY | SR_IO);
-
- if (!value && (hostdata->select_time < HZ/4)) {
- /* RvC: we still must wait for a device response */
- hostdata->select_time++; /* after 25 ticks the device has failed */
- NCR5380_set_timer(hostdata, 1);
- return 0; /* RvC: we return here with hostdata->selecting set,
- to go to sleep */
- }
+ err = NCR5380_poll_politely(instance, STATUS_REG, SR_BSY, SR_BSY,
+ msecs_to_jiffies(250));
- hostdata->selecting = NULL;/* clear this pointer, because we passed the
- waiting period */
if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) == (SR_SEL | SR_IO)) {
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
NCR5380_reselect(instance);
@@ -1376,6 +1330,17 @@ part2:
NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
return -1;
}
+
+ if (err < 0) {
+ NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
+ cmd->result = DID_BAD_TARGET << 16;
+ cmd->scsi_done(cmd);
+ NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
+ dprintk(NDEBUG_SELECTION, "scsi%d : target did not respond within 250ms\n",
+ instance->host_no);
+ return 0;
+ }
+
/*
* No less than two deskew delays after the initiator detects the
* BSY signal is true, it shall release the SEL signal and may
@@ -1386,15 +1351,6 @@ part2:
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
- if (!(NCR5380_read(STATUS_REG) & SR_BSY)) {
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
- cmd->result = DID_BAD_TARGET << 16;
- cmd->scsi_done(cmd);
- NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
- dprintk(NDEBUG_SELECTION, "scsi%d : target did not respond within 250ms\n", instance->host_no);
- return 0;
- }
-
/*
* Since we followed the SCSI spec, and raised ATN while SEL
* was true but before BSY was false during selection, the information
Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h 2016-01-03 16:03:26.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h 2016-01-03 16:03:28.000000000 +1100
@@ -267,8 +267,6 @@ struct NCR5380_hostdata {
volatile struct scsi_cmnd *disconnected_queue; /* waiting for reconnect */
int flags;
unsigned long time_expires; /* in jiffies, set prior to sleeping */
- int select_time; /* timer in select for target response */
- volatile struct scsi_cmnd *selecting;
struct delayed_work coroutine; /* our co-routine */
struct scsi_eh_save ses;
char info[256];
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c 2016-01-03 16:03:26.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c 2016-01-03 16:03:28.000000000 +1100
@@ -1431,7 +1431,7 @@ static int NCR5380_select(struct Scsi_Ho
unsigned char tmp[3], phase;
unsigned char *data;
int len;
- unsigned long timeout;
+ int err;
unsigned long flags;
NCR5380_dprint(NDEBUG_ARBITRATION, instance);
@@ -1605,25 +1605,8 @@ static int NCR5380_select(struct Scsi_Ho
* selection.
*/
- timeout = jiffies + msecs_to_jiffies(250);
-
- /*
- * XXX very interesting - we're seeing a bounce where the BSY we
- * asserted is being reflected / still asserted (propagation delay?)
- * and it's detecting as true. Sigh.
- */
-
-#if 0
- /* ++roman: If a target conformed to the SCSI standard, it wouldn't assert
- * IO while SEL is true. But again, there are some disks out the in the
- * world that do that nevertheless. (Somebody claimed that this announces
- * reselection capability of the target.) So we better skip that test and
- * only wait for BSY... (Famous german words: Der Klügere gibt nach :-)
- */
-
- while (time_before(jiffies, timeout) &&
- !(NCR5380_read(STATUS_REG) & (SR_BSY | SR_IO)))
- ;
+ err = NCR5380_poll_politely(instance, STATUS_REG, SR_BSY, SR_BSY,
+ msecs_to_jiffies(250));
if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) == (SR_SEL | SR_IO)) {
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
@@ -1633,22 +1616,8 @@ static int NCR5380_select(struct Scsi_Ho
NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
return -1;
}
-#else
- while (time_before(jiffies, timeout) && !(NCR5380_read(STATUS_REG) & SR_BSY))
- ;
-#endif
-
- /*
- * No less than two deskew delays after the initiator detects the
- * BSY signal is true, it shall release the SEL signal and may
- * change the DATA BUS. -wingel
- */
- udelay(1);
-
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
-
- if (!(NCR5380_read(STATUS_REG) & SR_BSY)) {
+ if (err < 0) {
NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
cmd->result = DID_BAD_TARGET << 16;
#ifdef SUPPORT_TAGS
@@ -1661,6 +1630,16 @@ static int NCR5380_select(struct Scsi_Ho
}
/*
+ * No less than two deskew delays after the initiator detects the
+ * BSY signal is true, it shall release the SEL signal and may
+ * change the DATA BUS. -wingel
+ */
+
+ udelay(1);
+
+ NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
+
+ /*
* Since we followed the SCSI spec, and raised ATN while SEL
* was true but before BSY was false during selection, the information
* transfer phase should be a MESSAGE OUT phase so that we can send the
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Finn Thain <fthain@telegraphics.com.au> |
|---|---|
| Date | 2016-01-03 06:40 +0100 |
| Subject | [PATCH v4 27/78] ncr5380: Add missing lock in eh_abort_handler |
| Message-ID | <qMJyy-1gX-13@gated-at.bofh.it> |
| In reply to | #1300181 |
The host spin lock needs to be acquired by NCR5380_abort() before it calls
NCR5380_select(). This patch doesn't actually fix the EH issues in this
driver but it does avoid this:
BUG: spinlock already unlocked on CPU#0, kworker/u4:1/14
lock: 0xc0c0f834, .magic: dead4ead, .owner: <none>/-1, .owner_cpu: -1
CPU: 0 PID: 14 Comm: kworker/u4:1 Not tainted 3.15.5 #5
Workqueue: scsi_tmf_4 scmd_eh_abort_handler
Call Trace:
[ef885d70] [c0008acc] show_stack+0x70/0x1bc (unreliable)
[ef885db0] [c0492a00] dump_stack+0x84/0x684
[ef885dc0] [c006f314] spin_dump+0xd0/0xe8
[ef885dd0] [c006f460] do_raw_spin_unlock+0xd4/0xd8
[ef885df0] [c0491c8c] _raw_spin_unlock_irq+0x10/0x3c
[ef885e00] [f381fe3c] NCR5380_select+0x3e4/0x6e8 [dmx3191d]
[ef885e40] [f382026c] NCR5380_abort+0x12c/0x190 [dmx3191d]
[ef885e60] [c02fec9c] scmd_eh_abort_handler+0x100/0x460
[ef885e80] [c0046470] process_one_work+0x16c/0x420
[ef885ea0] [c0046870] worker_thread+0x14c/0x430
[ef885ed0] [c004e4f4] kthread+0xd8/0xec
[ef885f40] [c00124d4] ret_from_kernel_thread+0x5c/0x64
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Tested-by: Ondrej Zary <linux@rainbow-software.org>
---
drivers/scsi/NCR5380.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c 2016-01-03 16:03:35.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c 2016-01-03 16:03:37.000000000 +1100
@@ -2374,6 +2374,7 @@ static int NCR5380_abort(struct scsi_cmn
scmd_printk(KERN_WARNING, cmd, "aborting command\n");
+ spin_lock_irq(instance->host_lock);
NCR5380_print_status(instance);
dprintk(NDEBUG_ABORT, "scsi%d : abort called\n", instance->host_no);
@@ -2420,6 +2421,7 @@ static int NCR5380_abort(struct scsi_cmn
REMOVE(5, *prev, tmp, tmp->host_scribble);
(*prev) = (struct scsi_cmnd *) tmp->host_scribble;
tmp->host_scribble = NULL;
+ spin_unlock_irq(instance->host_lock);
tmp->result = DID_ABORT << 16;
dprintk(NDEBUG_ABORT, "scsi%d : abort removed command from issue queue.\n", instance->host_no);
tmp->scsi_done(tmp);
@@ -2443,6 +2445,7 @@ static int NCR5380_abort(struct scsi_cmn
*/
if (hostdata->connected) {
+ spin_unlock_irq(instance->host_lock);
dprintk(NDEBUG_ABORT, "scsi%d : abort failed, command connected.\n", instance->host_no);
return FAILED;
}
@@ -2475,8 +2478,10 @@ static int NCR5380_abort(struct scsi_cmn
if (cmd == tmp) {
dprintk(NDEBUG_ABORT, "scsi%d : aborting disconnected command.\n", instance->host_no);
- if (NCR5380_select(instance, cmd))
+ if (NCR5380_select(instance, cmd)) {
+ spin_unlock_irq(instance->host_lock);
return FAILED;
+ }
dprintk(NDEBUG_ABORT, "scsi%d : nexus reestablished.\n", instance->host_no);
do_abort(instance);
@@ -2486,6 +2491,7 @@ static int NCR5380_abort(struct scsi_cmn
REMOVE(5, *prev, tmp, tmp->host_scribble);
*prev = (struct scsi_cmnd *) tmp->host_scribble;
tmp->host_scribble = NULL;
+ spin_unlock_irq(instance->host_lock);
tmp->result = DID_ABORT << 16;
tmp->scsi_done(tmp);
return SUCCESS;
@@ -2500,6 +2506,7 @@ static int NCR5380_abort(struct scsi_cmn
* so we won't panic, but we will notify the user in case something really
* broke.
*/
+ spin_unlock_irq(instance->host_lock);
printk(KERN_WARNING "scsi%d : warning : SCSI command probably completed successfully\n"
" before abortion\n", instance->host_no);
return FAILED;
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Finn Thain <fthain@telegraphics.com.au> |
|---|---|
| Date | 2016-01-03 06:40 +0100 |
| Subject | [PATCH v4 20/78] ncr5380: Introduce unbound workqueue |
| Message-ID | <qMJyy-1gX-11@gated-at.bofh.it> |
| In reply to | #1300181 |
Allocate a work queue that will permit busy waiting and sleeping. This
means NCR5380_init() can potentially fail, so add this error path.
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Tested-by: Ondrej Zary <linux@rainbow-software.org>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
---
In subsequent patches, the work function adopts this work queue so it
can sleep while polling, which allows the removal of some flawed and
complicated code in NCR5380_select() in NCR5380.c.
Changed since v1:
- Dropped WQ_CPU_INTENSIVE flag because Documentation/workqueue.txt says it
"is meaningless for unbound wq".
---
drivers/scsi/NCR5380.c | 15 +++++++++++----
drivers/scsi/NCR5380.h | 1 +
drivers/scsi/arm/cumana_1.c | 8 ++++++--
drivers/scsi/arm/oak.c | 8 ++++++--
drivers/scsi/atari_NCR5380.c | 8 +++++++-
drivers/scsi/atari_scsi.c | 5 ++++-
drivers/scsi/dmx3191d.c | 17 +++++++++++------
drivers/scsi/dtc.c | 11 +++++++++--
drivers/scsi/g_NCR5380.c | 31 +++++++++++++++----------------
drivers/scsi/mac_scsi.c | 5 ++++-
drivers/scsi/pas16.c | 10 ++++++++--
drivers/scsi/sun3_scsi.c | 5 ++++-
drivers/scsi/t128.c | 13 ++++++++++---
13 files changed, 96 insertions(+), 41 deletions(-)
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c 2016-01-03 16:03:20.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c 2016-01-03 16:03:23.000000000 +1100
@@ -514,7 +514,7 @@ static int should_disconnect(unsigned ch
static void NCR5380_set_timer(struct NCR5380_hostdata *hostdata, unsigned long timeout)
{
hostdata->time_expires = jiffies + timeout;
- schedule_delayed_work(&hostdata->coroutine, timeout);
+ queue_delayed_work(hostdata->work_q, &hostdata->coroutine, timeout);
}
@@ -791,7 +791,12 @@ static int NCR5380_init(struct Scsi_Host
hostdata->disconnected_queue = NULL;
INIT_DELAYED_WORK(&hostdata->coroutine, NCR5380_main);
-
+ hostdata->work_q = alloc_workqueue("ncr5380_%d",
+ WQ_UNBOUND | WQ_MEM_RECLAIM,
+ 1, instance->host_no);
+ if (!hostdata->work_q)
+ return -ENOMEM;
+
/* The CHECK code seems to break the 53C400. Will check it later maybe */
if (flags & FLAG_NCR53C400)
hostdata->flags = FLAG_HAS_LAST_BYTE_SENT | flags;
@@ -872,6 +877,7 @@ static void NCR5380_exit(struct Scsi_Hos
struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
cancel_delayed_work_sync(&hostdata->coroutine);
+ destroy_workqueue(hostdata->work_q);
}
/**
@@ -932,7 +938,7 @@ static int NCR5380_queue_command_lck(str
/* Run the coroutine if it isn't already running. */
/* Kick off command processing */
- schedule_delayed_work(&hostdata->coroutine, 0);
+ queue_delayed_work(hostdata->work_q, &hostdata->coroutine, 0);
return 0;
}
@@ -1128,7 +1134,8 @@ static irqreturn_t NCR5380_intr(int dumm
} /* if BASR_IRQ */
spin_unlock_irqrestore(instance->host_lock, flags);
if(!done)
- schedule_delayed_work(&hostdata->coroutine, 0);
+ queue_delayed_work(hostdata->work_q,
+ &hostdata->coroutine, 0);
} while (!done);
return IRQ_HANDLED;
}
Index: linux/drivers/scsi/NCR5380.h
===================================================================
--- linux.orig/drivers/scsi/NCR5380.h 2016-01-03 16:03:17.000000000 +1100
+++ linux/drivers/scsi/NCR5380.h 2016-01-03 16:03:23.000000000 +1100
@@ -284,6 +284,7 @@ struct NCR5380_hostdata {
unsigned spin_max_r;
unsigned spin_max_w;
#endif
+ struct workqueue_struct *work_q;
};
#ifdef __KERNEL__
Index: linux/drivers/scsi/arm/cumana_1.c
===================================================================
--- linux.orig/drivers/scsi/arm/cumana_1.c 2016-01-03 16:03:22.000000000 +1100
+++ linux/drivers/scsi/arm/cumana_1.c 2016-01-03 16:03:23.000000000 +1100
@@ -238,7 +238,9 @@ static int cumanascsi1_probe(struct expa
host->irq = ec->irq;
- NCR5380_init(host, 0);
+ ret = NCR5380_init(host, 0);
+ if (ret)
+ goto out_unmap;
NCR5380_maybe_reset_bus(host);
@@ -250,7 +252,7 @@ static int cumanascsi1_probe(struct expa
if (ret) {
printk("scsi%d: IRQ%d not free: %d\n",
host->host_no, host->irq, ret);
- goto out_unmap;
+ goto out_exit;
}
ret = scsi_add_host(host, &ec->dev);
@@ -262,6 +264,8 @@ static int cumanascsi1_probe(struct expa
out_free_irq:
free_irq(host->irq, host);
+ out_exit:
+ NCR5380_exit(host);
out_unmap:
iounmap(priv(host)->base);
iounmap(priv(host)->dma);
Index: linux/drivers/scsi/arm/oak.c
===================================================================
--- linux.orig/drivers/scsi/arm/oak.c 2016-01-03 16:03:03.000000000 +1100
+++ linux/drivers/scsi/arm/oak.c 2016-01-03 16:03:23.000000000 +1100
@@ -143,17 +143,21 @@ static int oakscsi_probe(struct expansio
host->irq = NO_IRQ;
host->n_io_port = 255;
- NCR5380_init(host, 0);
+ ret = NCR5380_init(host, 0);
+ if (ret)
+ goto out_unmap;
NCR5380_maybe_reset_bus(host);
ret = scsi_add_host(host, &ec->dev);
if (ret)
- goto out_unmap;
+ goto out_exit;
scsi_scan_host(host);
goto out;
+ out_exit:
+ NCR5380_exit(host);
out_unmap:
iounmap(priv(host)->base);
unreg:
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c 2016-01-03 16:03:19.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c 2016-01-03 16:03:23.000000000 +1100
@@ -643,7 +643,7 @@ static inline void queue_main(struct NCR
queue it on the 'immediate' task queue, to be processed
immediately after the current interrupt processing has
finished. */
- schedule_work(&hostdata->main_task);
+ queue_work(hostdata->work_q, &hostdata->main_task);
}
/* else: nothing to do: the running NCR5380_main() will pick up
any newly queued command. */
@@ -832,6 +832,11 @@ static int __init NCR5380_init(struct Sc
hostdata->flags = flags;
INIT_WORK(&hostdata->main_task, NCR5380_main);
+ hostdata->work_q = alloc_workqueue("ncr5380_%d",
+ WQ_UNBOUND | WQ_MEM_RECLAIM,
+ 1, instance->host_no);
+ if (!hostdata->work_q)
+ return -ENOMEM;
prepare_info(instance);
@@ -907,6 +912,7 @@ static void NCR5380_exit(struct Scsi_Hos
struct NCR5380_hostdata *hostdata = shost_priv(instance);
cancel_work_sync(&hostdata->main_task);
+ destroy_workqueue(hostdata->work_q);
}
/**
Index: linux/drivers/scsi/atari_scsi.c
===================================================================
--- linux.orig/drivers/scsi/atari_scsi.c 2016-01-03 16:03:09.000000000 +1100
+++ linux/drivers/scsi/atari_scsi.c 2016-01-03 16:03:23.000000000 +1100
@@ -885,7 +885,9 @@ static int __init atari_scsi_probe(struc
#endif
host_flags |= setup_toshiba_delay > 0 ? FLAG_TOSHIBA_DELAY : 0;
- NCR5380_init(instance, host_flags);
+ error = NCR5380_init(instance, host_flags);
+ if (error)
+ goto fail_init;
if (IS_A_TT()) {
error = request_irq(instance->irq, scsi_tt_intr, 0,
@@ -947,6 +949,7 @@ fail_host:
free_irq(instance->irq, instance);
fail_irq:
NCR5380_exit(instance);
+fail_init:
scsi_host_put(instance);
fail_alloc:
if (atari_dma_buffer)
Index: linux/drivers/scsi/dmx3191d.c
===================================================================
--- linux.orig/drivers/scsi/dmx3191d.c 2016-01-03 16:03:03.000000000 +1100
+++ linux/drivers/scsi/dmx3191d.c 2016-01-03 16:03:23.000000000 +1100
@@ -95,7 +95,9 @@ static int dmx3191d_probe_one(struct pci
*/
shost->irq = NO_IRQ;
- NCR5380_init(shost, FLAG_NO_PSEUDO_DMA | FLAG_DTC3181E);
+ error = NCR5380_init(shost, FLAG_NO_PSEUDO_DMA | FLAG_DTC3181E);
+ if (error)
+ goto out_host_put;
NCR5380_maybe_reset_bus(shost);
@@ -103,11 +105,15 @@ static int dmx3191d_probe_one(struct pci
error = scsi_add_host(shost, &pdev->dev);
if (error)
- goto out_release_region;
+ goto out_exit;
scsi_scan_host(shost);
return 0;
+out_exit:
+ NCR5380_exit(shost);
+out_host_put:
+ scsi_host_put(shost);
out_release_region:
release_region(io, DMX3191D_REGION_LEN);
out_disable_device:
@@ -119,15 +125,14 @@ static int dmx3191d_probe_one(struct pci
static void dmx3191d_remove_one(struct pci_dev *pdev)
{
struct Scsi_Host *shost = pci_get_drvdata(pdev);
+ unsigned long io = shost->io_port;
scsi_remove_host(shost);
NCR5380_exit(shost);
-
- release_region(shost->io_port, DMX3191D_REGION_LEN);
- pci_disable_device(pdev);
-
scsi_host_put(shost);
+ release_region(io, DMX3191D_REGION_LEN);
+ pci_disable_device(pdev);
}
static struct pci_device_id dmx3191d_pci_tbl[] = {
Index: linux/drivers/scsi/dtc.c
===================================================================
--- linux.orig/drivers/scsi/dtc.c 2016-01-03 16:03:22.000000000 +1100
+++ linux/drivers/scsi/dtc.c 2016-01-03 16:03:23.000000000 +1100
@@ -230,12 +230,13 @@ static int __init dtc_detect(struct scsi
found:
instance = scsi_register(tpnt, sizeof(struct NCR5380_hostdata));
if (instance == NULL)
- break;
+ goto out_unmap;
instance->base = addr;
((struct NCR5380_hostdata *)(instance)->hostdata)->base = base;
- NCR5380_init(instance, 0);
+ if (NCR5380_init(instance, 0))
+ goto out_unregister;
NCR5380_maybe_reset_bus(instance);
@@ -275,6 +276,12 @@ found:
++count;
}
return count;
+
+out_unregister:
+ scsi_unregister(instance);
+out_unmap:
+ iounmap(base);
+ return count;
}
/*
Index: linux/drivers/scsi/g_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/g_NCR5380.c 2016-01-03 16:03:20.000000000 +1100
+++ linux/drivers/scsi/g_NCR5380.c 2016-01-03 16:03:23.000000000 +1100
@@ -239,9 +239,6 @@ static int __init do_DTC3181E_setup(char
* and DTC436(ISAPnP) controllers. If overrides have been set we use
* them.
*
- * The caller supplied NCR5380_init function is invoked from here, before
- * the interrupt line is taken.
- *
* Locks: none
*/
@@ -402,15 +399,8 @@ static int __init generic_NCR5380_detect
}
#endif
instance = scsi_register(tpnt, sizeof(struct NCR5380_hostdata));
- if (instance == NULL) {
-#ifndef SCSI_G_NCR5380_MEM
- release_region(overrides[current_override].NCR5380_map_name, region_size);
-#else
- iounmap(iomem);
- release_mem_region(base, NCR5380_region_size);
-#endif
- continue;
- }
+ if (instance == NULL)
+ goto out_release;
#ifndef SCSI_G_NCR5380_MEM
instance->io_port = overrides[current_override].NCR5380_map_name;
@@ -427,7 +417,8 @@ static int __init generic_NCR5380_detect
((struct NCR5380_hostdata *)instance->hostdata)->iomem = iomem;
#endif
- NCR5380_init(instance, flags);
+ if (NCR5380_init(instance, flags))
+ goto out_unregister;
if (overrides[current_override].board == BOARD_NCR53C400)
NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);
@@ -459,6 +450,17 @@ static int __init generic_NCR5380_detect
++count;
}
return count;
+
+out_unregister:
+ scsi_unregister(instance);
+out_release:
+#ifndef SCSI_G_NCR5380_MEM
+ release_region(overrides[current_override].NCR5380_map_name, region_size);
+#else
+ iounmap(iomem);
+ release_mem_region(base, NCR5380_region_size);
+#endif
+ return count;
}
/**
@@ -475,15 +477,12 @@ static int generic_NCR5380_release_resou
if (instance->irq != NO_IRQ)
free_irq(instance->irq, instance);
NCR5380_exit(instance);
-
#ifndef SCSI_G_NCR5380_MEM
release_region(instance->io_port, instance->n_io_port);
#else
iounmap(((struct NCR5380_hostdata *)instance->hostdata)->iomem);
release_mem_region(instance->base, NCR5380_region_size);
#endif
-
-
return 0;
}
Index: linux/drivers/scsi/mac_scsi.c
===================================================================
--- linux.orig/drivers/scsi/mac_scsi.c 2016-01-03 16:03:09.000000000 +1100
+++ linux/drivers/scsi/mac_scsi.c 2016-01-03 16:03:23.000000000 +1100
@@ -382,7 +382,9 @@ static int __init mac_scsi_probe(struct
#endif
host_flags |= setup_toshiba_delay > 0 ? FLAG_TOSHIBA_DELAY : 0;
- NCR5380_init(instance, host_flags);
+ error = NCR5380_init(instance, host_flags);
+ if (error)
+ goto fail_init;
if (instance->irq != NO_IRQ) {
error = request_irq(instance->irq, macscsi_intr, IRQF_SHARED,
@@ -407,6 +409,7 @@ fail_host:
free_irq(instance->irq, instance);
fail_irq:
NCR5380_exit(instance);
+fail_init:
scsi_host_put(instance);
return error;
}
Index: linux/drivers/scsi/pas16.c
===================================================================
--- linux.orig/drivers/scsi/pas16.c 2016-01-03 16:03:22.000000000 +1100
+++ linux/drivers/scsi/pas16.c 2016-01-03 16:03:23.000000000 +1100
@@ -378,11 +378,12 @@ static int __init pas16_detect(struct sc
instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata));
if(instance == NULL)
- break;
+ goto out;
instance->io_port = io_port;
- NCR5380_init(instance, 0);
+ if (NCR5380_init(instance, 0))
+ goto out_unregister;
NCR5380_maybe_reset_bus(instance);
@@ -418,6 +419,11 @@ static int __init pas16_detect(struct sc
++count;
}
return count;
+
+out_unregister:
+ scsi_unregister(instance);
+out:
+ return count;
}
/*
Index: linux/drivers/scsi/sun3_scsi.c
===================================================================
--- linux.orig/drivers/scsi/sun3_scsi.c 2016-01-03 16:03:09.000000000 +1100
+++ linux/drivers/scsi/sun3_scsi.c 2016-01-03 16:03:23.000000000 +1100
@@ -557,7 +557,9 @@ static int __init sun3_scsi_probe(struct
host_flags |= setup_use_tagged_queuing > 0 ? FLAG_TAGGED_QUEUING : 0;
#endif
- NCR5380_init(instance, host_flags);
+ error = NCR5380_init(instance, host_flags);
+ if (error)
+ goto fail_init;
error = request_irq(instance->irq, scsi_sun3_intr, 0,
"NCR5380", instance);
@@ -604,6 +606,7 @@ fail_host:
free_irq(instance->irq, instance);
fail_irq:
NCR5380_exit(instance);
+fail_init:
scsi_host_put(instance);
fail_alloc:
if (udc_regs)
Index: linux/drivers/scsi/t128.c
===================================================================
--- linux.orig/drivers/scsi/t128.c 2016-01-03 16:03:22.000000000 +1100
+++ linux/drivers/scsi/t128.c 2016-01-03 16:03:23.000000000 +1100
@@ -208,12 +208,13 @@ static int __init t128_detect(struct scs
found:
instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata));
if(instance == NULL)
- break;
-
+ goto out_unmap;
+
instance->base = base;
((struct NCR5380_hostdata *)instance->hostdata)->base = p;
- NCR5380_init(instance, 0);
+ if (NCR5380_init(instance, 0))
+ goto out_unregister;
NCR5380_maybe_reset_bus(instance);
@@ -246,6 +247,12 @@ found:
++count;
}
return count;
+
+out_unregister:
+ scsi_unregister(instance);
+out_unmap:
+ iounmap(p);
+ return count;
}
static int t128_release(struct Scsi_Host *shost)
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Finn Thain <fthain@telegraphics.com.au> |
|---|---|
| Date | 2016-01-03 06:40 +0100 |
| Subject | [PATCH v4 11/78] ncr5380: Simplify bus reset handlers |
| Message-ID | <qMJyy-1gX-17@gated-at.bofh.it> |
| In reply to | #1300181 |
Make use of do_reset() in the bus reset handler in atari_NCR5380.c. The
version in NCR5380.c already does so. Keep them in sync.
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Tested-by: Ondrej Zary <linux@rainbow-software.org>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
---
Bus reset handlers in both core drivers still have serious problems for
EH purposes. Those problems are addressed later in this series.
---
drivers/scsi/NCR5380.c | 20 +++++++++++---------
drivers/scsi/atari_NCR5380.c | 30 ++++++++++++------------------
2 files changed, 23 insertions(+), 27 deletions(-)
Index: linux/drivers/scsi/NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/NCR5380.c 2016-01-03 16:03:09.000000000 +1100
+++ linux/drivers/scsi/NCR5380.c 2016-01-03 16:03:12.000000000 +1100
@@ -668,7 +668,7 @@ static void prepare_info(struct Scsi_Hos
* Locks: called functions disable irqs
*/
-static void NCR5380_print_status(struct Scsi_Host *instance)
+static void __maybe_unused NCR5380_print_status(struct Scsi_Host *instance)
{
NCR5380_dprint(NDEBUG_ANY, instance);
NCR5380_dprint_phase(NDEBUG_ANY, instance);
@@ -2693,24 +2693,26 @@ static int NCR5380_abort(struct scsi_cmn
}
-/*
- * Function : int NCR5380_bus_reset (struct scsi_cmnd *cmd)
- *
- * Purpose : reset the SCSI bus.
- *
- * Returns : SUCCESS
+/**
+ * NCR5380_bus_reset - reset the SCSI bus
+ * @cmd: SCSI command undergoing EH
*
- * Locks: host lock taken by caller
+ * Returns SUCCESS
*/
static int NCR5380_bus_reset(struct scsi_cmnd *cmd)
{
struct Scsi_Host *instance = cmd->device->host;
+ spin_lock_irq(instance->host_lock);
+
+#if (NDEBUG & NDEBUG_ANY)
+ scmd_printk(KERN_INFO, cmd, "performing bus reset\n");
NCR5380_print_status(instance);
+#endif
- spin_lock_irq(instance->host_lock);
do_reset(instance);
+
spin_unlock_irq(instance->host_lock);
return SUCCESS;
Index: linux/drivers/scsi/atari_NCR5380.c
===================================================================
--- linux.orig/drivers/scsi/atari_NCR5380.c 2016-01-03 16:03:09.000000000 +1100
+++ linux/drivers/scsi/atari_NCR5380.c 2016-01-03 16:03:12.000000000 +1100
@@ -719,7 +719,7 @@ static void lprint_Scsi_Cmnd(struct scsi
printk("\n");
}
-static void NCR5380_print_status(struct Scsi_Host *instance)
+static void __maybe_unused NCR5380_print_status(struct Scsi_Host *instance)
{
struct NCR5380_hostdata *hostdata;
struct scsi_cmnd *ptr;
@@ -2982,13 +2982,11 @@ int NCR5380_abort(struct scsi_cmnd *cmd)
}
-/*
- * Function : int NCR5380_reset (struct scsi_cmnd *cmd)
- *
- * Purpose : reset the SCSI bus.
- *
- * Returns : SUCCESS or FAILURE
+/**
+ * NCR5380_bus_reset - reset the SCSI bus
+ * @cmd: SCSI command undergoing EH
*
+ * Returns SUCCESS
*/
static int NCR5380_bus_reset(struct scsi_cmnd *cmd)
@@ -2998,22 +2996,19 @@ static int NCR5380_bus_reset(struct scsi
int i;
unsigned long flags;
+ local_irq_save(flags);
+
+#if (NDEBUG & NDEBUG_ANY)
+ scmd_printk(KERN_INFO, cmd, "performing bus reset\n");
NCR5380_print_status(instance);
+#endif
+
+ do_reset(instance);
- /* get in phase */
- NCR5380_write(TARGET_COMMAND_REG,
- PHASE_SR_TO_TCR(NCR5380_read(STATUS_REG)));
- /* assert RST */
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST);
- udelay(40);
/* reset NCR registers */
- NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
NCR5380_write(MODE_REG, MR_BASE);
NCR5380_write(TARGET_COMMAND_REG, 0);
NCR5380_write(SELECT_ENABLE_REG, 0);
- /* ++roman: reset interrupt condition! otherwise no interrupts don't get
- * through anymore ... */
- (void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
/* After the reset, there are no more connected or disconnected commands
* and no busy units; so clear the low-level status here to avoid
@@ -3028,7 +3023,6 @@ static int NCR5380_bus_reset(struct scsi
if (hostdata->disconnected_queue)
dprintk(NDEBUG_ABORT, "scsi%d: reset aborted disconnected command(s)\n", H_NO(cmd));
- local_irq_save(flags);
hostdata->issue_queue = NULL;
hostdata->connected = NULL;
hostdata->disconnected_queue = NULL;
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
Page 3 of 5 — ← Prev page 1 2 [3] 4 5 Next page →
Back to top | Article view | linux.kernel
csiph-web