diff options
author | Finn Thain <fthain@telegraphics.com.au> | 2014-11-12 00:12:18 -0500 |
---|---|---|
committer | Christoph Hellwig <hch@lst.de> | 2014-11-20 03:11:18 -0500 |
commit | ff50f9ed0fcae6c890cc6d478814ec8cbb24feb1 (patch) | |
tree | 00e92cc5e4e63c6d563a4fe25934b7ffbe9b3115 /drivers/scsi/atari_NCR5380.c | |
parent | 8dad0c51dac3f906b213ef3486cad39a06419252 (diff) |
atari_NCR5380: Merge from NCR5380.c
The NCR5380.c core driver has moved on since the atari_NCR5380.c fork.
Some of those changes are also relevant to atari_NCR5380.c so apply them
there as well.
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'drivers/scsi/atari_NCR5380.c')
-rw-r--r-- | drivers/scsi/atari_NCR5380.c | 205 |
1 files changed, 85 insertions, 120 deletions
diff --git a/drivers/scsi/atari_NCR5380.c b/drivers/scsi/atari_NCR5380.c index 1331b8cf5fe9..7bbfa1b777c3 100644 --- a/drivers/scsi/atari_NCR5380.c +++ b/drivers/scsi/atari_NCR5380.c | |||
@@ -104,27 +104,7 @@ | |||
104 | 104 | ||
105 | /* | 105 | /* |
106 | * Design | 106 | * Design |
107 | * Issues : | ||
108 | * | 107 | * |
109 | * The other Linux SCSI drivers were written when Linux was Intel PC-only, | ||
110 | * and specifically for each board rather than each chip. This makes their | ||
111 | * adaptation to platforms like the Mac (Some of which use NCR5380's) | ||
112 | * more difficult than it has to be. | ||
113 | * | ||
114 | * Also, many of the SCSI drivers were written before the command queuing | ||
115 | * routines were implemented, meaning their implementations of queued | ||
116 | * commands were hacked on rather than designed in from the start. | ||
117 | * | ||
118 | * When I designed the Linux SCSI drivers I figured that | ||
119 | * while having two different SCSI boards in a system might be useful | ||
120 | * for debugging things, two of the same type wouldn't be used. | ||
121 | * Well, I was wrong and a number of users have mailed me about running | ||
122 | * multiple high-performance SCSI boards in a server. | ||
123 | * | ||
124 | * Finally, when I get questions from users, I have no idea what | ||
125 | * revision of my driver they are running. | ||
126 | * | ||
127 | * This driver attempts to address these problems : | ||
128 | * This is a generic 5380 driver. To use it on a different platform, | 108 | * This is a generic 5380 driver. To use it on a different platform, |
129 | * one simply writes appropriate system specific macros (ie, data | 109 | * one simply writes appropriate system specific macros (ie, data |
130 | * transfer - some PC's will use the I/O bus, 68K's must use | 110 | * transfer - some PC's will use the I/O bus, 68K's must use |
@@ -139,11 +119,6 @@ | |||
139 | * allowing multiple commands to propagate all the way to a SCSI-II device | 119 | * allowing multiple commands to propagate all the way to a SCSI-II device |
140 | * while a command is already executing. | 120 | * while a command is already executing. |
141 | * | 121 | * |
142 | * To solve the multiple-boards-in-the-same-system problem, | ||
143 | * there is a separate instance structure for each instance | ||
144 | * of a 5380 in the system. So, multiple NCR5380 drivers will | ||
145 | * be able to coexist with appropriate changes to the high level | ||
146 | * SCSI code. | ||
147 | * | 122 | * |
148 | * Issues specific to the NCR5380 : | 123 | * Issues specific to the NCR5380 : |
149 | * | 124 | * |
@@ -168,19 +143,17 @@ | |||
168 | * Architecture : | 143 | * Architecture : |
169 | * | 144 | * |
170 | * At the heart of the design is a coroutine, NCR5380_main, | 145 | * At the heart of the design is a coroutine, NCR5380_main, |
171 | * which is started when not running by the interrupt handler, | 146 | * which is started from a workqueue for each NCR5380 host in the |
172 | * timer, and queue command function. It attempts to establish | 147 | * system. It attempts to establish I_T_L or I_T_L_Q nexuses by |
173 | * I_T_L or I_T_L_Q nexuses by removing the commands from the | 148 | * removing the commands from the issue queue and calling |
174 | * issue queue and calling NCR5380_select() if a nexus | 149 | * NCR5380_select() if a nexus is not established. |
175 | * is not established. | ||
176 | * | 150 | * |
177 | * Once a nexus is established, the NCR5380_information_transfer() | 151 | * Once a nexus is established, the NCR5380_information_transfer() |
178 | * phase goes through the various phases as instructed by the target. | 152 | * phase goes through the various phases as instructed by the target. |
179 | * if the target goes into MSG IN and sends a DISCONNECT message, | 153 | * if the target goes into MSG IN and sends a DISCONNECT message, |
180 | * the command structure is placed into the per instance disconnected | 154 | * the command structure is placed into the per instance disconnected |
181 | * queue, and NCR5380_main tries to find more work. If USLEEP | 155 | * queue, and NCR5380_main tries to find more work. If the target is |
182 | * was defined, and the target is idle for too long, the system | 156 | * idle for too long, the system will try to sleep. |
183 | * will try to sleep. | ||
184 | * | 157 | * |
185 | * If a command has disconnected, eventually an interrupt will trigger, | 158 | * If a command has disconnected, eventually an interrupt will trigger, |
186 | * calling NCR5380_intr() which will in turn call NCR5380_reselect | 159 | * calling NCR5380_intr() which will in turn call NCR5380_reselect |
@@ -206,6 +179,9 @@ | |||
206 | * AUTOSENSE - if defined, REQUEST SENSE will be performed automatically | 179 | * AUTOSENSE - if defined, REQUEST SENSE will be performed automatically |
207 | * for commands that return with a CHECK CONDITION status. | 180 | * for commands that return with a CHECK CONDITION status. |
208 | * | 181 | * |
182 | * DIFFERENTIAL - if defined, NCR53c81 chips will use external differential | ||
183 | * transceivers. | ||
184 | * | ||
209 | * LINKED - if defined, linked commands are supported. | 185 | * LINKED - if defined, linked commands are supported. |
210 | * | 186 | * |
211 | * REAL_DMA - if defined, REAL DMA is used during the data transfer phases. | 187 | * REAL_DMA - if defined, REAL DMA is used during the data transfer phases. |
@@ -218,6 +194,9 @@ | |||
218 | * | 194 | * |
219 | * NCR5380_write(register, value) - write to the specific register | 195 | * NCR5380_write(register, value) - write to the specific register |
220 | * | 196 | * |
197 | * NCR5380_implementation_fields - additional fields needed for this | ||
198 | * specific implementation of the NCR5380 | ||
199 | * | ||
221 | * Either real DMA *or* pseudo DMA may be implemented | 200 | * Either real DMA *or* pseudo DMA may be implemented |
222 | * REAL functions : | 201 | * REAL functions : |
223 | * NCR5380_REAL_DMA should be defined if real DMA is to be used. | 202 | * NCR5380_REAL_DMA should be defined if real DMA is to be used. |
@@ -236,20 +215,6 @@ | |||
236 | * NCR5380_pwrite(instance, src, count) | 215 | * NCR5380_pwrite(instance, src, count) |
237 | * NCR5380_pread(instance, dst, count); | 216 | * NCR5380_pread(instance, dst, count); |
238 | * | 217 | * |
239 | * If nothing specific to this implementation needs doing (ie, with external | ||
240 | * hardware), you must also define | ||
241 | * | ||
242 | * NCR5380_queue_command | ||
243 | * NCR5380_reset | ||
244 | * NCR5380_abort | ||
245 | * | ||
246 | * to be the global entry points into the specific driver, ie | ||
247 | * #define NCR5380_queue_command t128_queue_command. | ||
248 | * | ||
249 | * If this is not done, the routines will be defined as static functions | ||
250 | * with the NCR5380* names and the user must provide a globally | ||
251 | * accessible wrapper function. | ||
252 | * | ||
253 | * The generic driver is initialized by calling NCR5380_init(instance), | 218 | * The generic driver is initialized by calling NCR5380_init(instance), |
254 | * after setting the appropriate host specific fields and ID. If the | 219 | * after setting the appropriate host specific fields and ID. If the |
255 | * driver wishes to autoprobe for an IRQ line, the NCR5380_probe_irq(instance, | 220 | * driver wishes to autoprobe for an IRQ line, the NCR5380_probe_irq(instance, |
@@ -489,13 +454,11 @@ static void merge_contiguous_buffers(struct scsi_cmnd *cmd) | |||
489 | #endif /* !defined(CONFIG_SUN3) */ | 454 | #endif /* !defined(CONFIG_SUN3) */ |
490 | } | 455 | } |
491 | 456 | ||
492 | /* | 457 | /** |
493 | * Function : void initialize_SCp(struct scsi_cmnd *cmd) | 458 | * initialize_SCp - init the scsi pointer field |
494 | * | 459 | * @cmd: command block to set up |
495 | * Purpose : initialize the saved data pointers for cmd to point to the | ||
496 | * start of the buffer. | ||
497 | * | 460 | * |
498 | * Inputs : cmd - scsi_cmnd structure to have pointers reset. | 461 | * Set up the internal fields in the SCSI command. |
499 | */ | 462 | */ |
500 | 463 | ||
501 | static inline void initialize_SCp(struct scsi_cmnd *cmd) | 464 | static inline void initialize_SCp(struct scsi_cmnd *cmd) |
@@ -548,12 +511,11 @@ static struct { | |||
548 | {0, NULL} | 511 | {0, NULL} |
549 | }; | 512 | }; |
550 | 513 | ||
551 | /* | 514 | /** |
552 | * Function : void NCR5380_print(struct Scsi_Host *instance) | 515 | * NCR5380_print - print scsi bus signals |
553 | * | 516 | * @instance: adapter state to dump |
554 | * Purpose : print the SCSI bus signals for debugging purposes | ||
555 | * | 517 | * |
556 | * Input : instance - which NCR5380 | 518 | * Print the SCSI bus signals for debugging purposes |
557 | */ | 519 | */ |
558 | 520 | ||
559 | static void NCR5380_print(struct Scsi_Host *instance) | 521 | static void NCR5380_print(struct Scsi_Host *instance) |
@@ -596,12 +558,13 @@ static struct { | |||
596 | {PHASE_UNKNOWN, "UNKNOWN"} | 558 | {PHASE_UNKNOWN, "UNKNOWN"} |
597 | }; | 559 | }; |
598 | 560 | ||
599 | /* | 561 | /** |
600 | * Function : void NCR5380_print_phase(struct Scsi_Host *instance) | 562 | * NCR5380_print_phase - show SCSI phase |
563 | * @instance: adapter to dump | ||
601 | * | 564 | * |
602 | * Purpose : print the current SCSI phase for debugging purposes | 565 | * Print the current SCSI phase for debugging purposes |
603 | * | 566 | * |
604 | * Input : instance - which NCR5380 | 567 | * Locks: none |
605 | */ | 568 | */ |
606 | 569 | ||
607 | static void NCR5380_print_phase(struct Scsi_Host *instance) | 570 | static void NCR5380_print_phase(struct Scsi_Host *instance) |
@@ -710,13 +673,12 @@ static void prepare_info(struct Scsi_Host *instance) | |||
710 | ""); | 673 | ""); |
711 | } | 674 | } |
712 | 675 | ||
713 | /* | 676 | /** |
714 | * Function : void NCR5380_print_status (struct Scsi_Host *instance) | 677 | * NCR5380_print_status - dump controller info |
715 | * | 678 | * @instance: controller to dump |
716 | * Purpose : print commands in the various queues, called from | ||
717 | * NCR5380_abort and NCR5380_debug to aid debugging. | ||
718 | * | 679 | * |
719 | * Inputs : instance, pointer to this instance. | 680 | * Print commands in the various queues, called from NCR5380_abort |
681 | * to aid debugging. | ||
720 | */ | 682 | */ |
721 | 683 | ||
722 | static void lprint_Scsi_Cmnd(struct scsi_cmnd *cmd) | 684 | static void lprint_Scsi_Cmnd(struct scsi_cmnd *cmd) |
@@ -807,16 +769,18 @@ static int __maybe_unused NCR5380_show_info(struct seq_file *m, | |||
807 | return 0; | 769 | return 0; |
808 | } | 770 | } |
809 | 771 | ||
810 | /* | 772 | /** |
811 | * Function : void NCR5380_init (struct Scsi_Host *instance) | 773 | * NCR5380_init - initialise an NCR5380 |
812 | * | 774 | * @instance: adapter to configure |
813 | * Purpose : initializes *instance and corresponding 5380 chip. | 775 | * @flags: control flags |
814 | * | 776 | * |
815 | * Inputs : instance - instantiation of the 5380 driver. | 777 | * Initializes *instance and corresponding 5380 chip, |
778 | * with flags OR'd into the initial flags value. | ||
816 | * | 779 | * |
817 | * Notes : I assume that the host, hostno, and id bits have been | 780 | * Notes : I assume that the host, hostno, and id bits have been |
818 | * set correctly. I don't care about the irq and other fields. | 781 | * set correctly. I don't care about the irq and other fields. |
819 | * | 782 | * |
783 | * Returns 0 for success | ||
820 | */ | 784 | */ |
821 | 785 | ||
822 | static int __init NCR5380_init(struct Scsi_Host *instance, int flags) | 786 | static int __init NCR5380_init(struct Scsi_Host *instance, int flags) |
@@ -861,27 +825,26 @@ static int __init NCR5380_init(struct Scsi_Host *instance, int flags) | |||
861 | return 0; | 825 | return 0; |
862 | } | 826 | } |
863 | 827 | ||
828 | /** | ||
829 | * NCR5380_exit - remove an NCR5380 | ||
830 | * @instance: adapter to remove | ||
831 | * | ||
832 | * Assumes that no more work can be queued (e.g. by NCR5380_intr). | ||
833 | */ | ||
834 | |||
864 | static void NCR5380_exit(struct Scsi_Host *instance) | 835 | static void NCR5380_exit(struct Scsi_Host *instance) |
865 | { | 836 | { |
866 | /* Empty, as we didn't schedule any delayed work */ | 837 | cancel_work_sync(&NCR5380_tqueue); |
867 | } | 838 | } |
868 | 839 | ||
869 | /* | 840 | /** |
870 | * Function : int NCR5380_queue_command (struct scsi_cmnd *cmd, | 841 | * NCR5380_queue_command - queue a command |
871 | * void (*done)(struct scsi_cmnd *)) | 842 | * @instance: the relevant SCSI adapter |
872 | * | 843 | * @cmd: SCSI command |
873 | * Purpose : enqueues a SCSI command | ||
874 | * | ||
875 | * Inputs : cmd - SCSI command, done - function called on completion, with | ||
876 | * a pointer to the command descriptor. | ||
877 | * | ||
878 | * Returns : 0 | ||
879 | * | ||
880 | * Side effects : | ||
881 | * cmd is added to the per instance issue_queue, with minor | ||
882 | * twiddling done to the host specific fields of cmd. If the | ||
883 | * main coroutine is not running, it is restarted. | ||
884 | * | 844 | * |
845 | * cmd is added to the per instance issue_queue, with minor | ||
846 | * twiddling done to the host specific fields of cmd. If the | ||
847 | * main coroutine is not running, it is restarted. | ||
885 | */ | 848 | */ |
886 | 849 | ||
887 | static int NCR5380_queue_command(struct Scsi_Host *instance, | 850 | static int NCR5380_queue_command(struct Scsi_Host *instance, |
@@ -935,6 +898,13 @@ static int NCR5380_queue_command(struct Scsi_Host *instance, | |||
935 | 898 | ||
936 | local_irq_save(flags); | 899 | local_irq_save(flags); |
937 | 900 | ||
901 | /* | ||
902 | * Insert the cmd into the issue queue. Note that REQUEST SENSE | ||
903 | * commands are added to the head of the queue since any command will | ||
904 | * clear the contingent allegiance condition that exists and the | ||
905 | * sense data is only guaranteed to be valid while the condition exists. | ||
906 | */ | ||
907 | |||
938 | if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) { | 908 | if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) { |
939 | LIST(cmd, hostdata->issue_queue); | 909 | LIST(cmd, hostdata->issue_queue); |
940 | SET_NEXT(cmd, hostdata->issue_queue); | 910 | SET_NEXT(cmd, hostdata->issue_queue); |
@@ -977,16 +947,15 @@ static inline void maybe_release_dma_irq(struct Scsi_Host *instance) | |||
977 | NCR5380_release_dma_irq(instance); | 947 | NCR5380_release_dma_irq(instance); |
978 | } | 948 | } |
979 | 949 | ||
980 | /* | 950 | /** |
981 | * Function : NCR5380_main (void) | 951 | * NCR5380_main - NCR state machines |
982 | * | 952 | * |
983 | * Purpose : NCR5380_main is a coroutine that runs as long as more work can | 953 | * NCR5380_main is a coroutine that runs as long as more work can |
984 | * be done on the NCR5380 host adapters in a system. Both | 954 | * be done on the NCR5380 host adapters in a system. Both |
985 | * NCR5380_queue_command() and NCR5380_intr() will try to start it | 955 | * NCR5380_queue_command() and NCR5380_intr() will try to start it |
986 | * in case it is not running. | 956 | * in case it is not running. |
987 | * | 957 | * |
988 | * NOTE : NCR5380_main exits with interrupts *disabled*, the caller should | 958 | * Locks: called as its own thread with no locks held. |
989 | * reenable them. This prevents reentrancy and kernel stack overflow. | ||
990 | */ | 959 | */ |
991 | 960 | ||
992 | static void NCR5380_main(struct work_struct *work) | 961 | static void NCR5380_main(struct work_struct *work) |
@@ -1239,15 +1208,14 @@ static void NCR5380_dma_complete(struct Scsi_Host *instance) | |||
1239 | #endif /* REAL_DMA */ | 1208 | #endif /* REAL_DMA */ |
1240 | 1209 | ||
1241 | 1210 | ||
1242 | /* | 1211 | /** |
1243 | * Function : void NCR5380_intr (int irq) | 1212 | * NCR5380_intr - generic NCR5380 irq handler |
1244 | * | 1213 | * @irq: interrupt number |
1245 | * Purpose : handle interrupts, reestablishing I_T_L or I_T_L_Q nexuses | 1214 | * @dev_id: device info |
1246 | * from the disconnected queue, and restarting NCR5380_main() | ||
1247 | * as required. | ||
1248 | * | ||
1249 | * Inputs : int irq, irq that caused this interrupt. | ||
1250 | * | 1215 | * |
1216 | * Handle interrupts, reestablishing I_T_L or I_T_L_Q nexuses | ||
1217 | * from the disconnected queue, and restarting NCR5380_main() | ||
1218 | * as required. | ||
1251 | */ | 1219 | */ |
1252 | 1220 | ||
1253 | static irqreturn_t NCR5380_intr(int irq, void *dev_id) | 1221 | static irqreturn_t NCR5380_intr(int irq, void *dev_id) |
@@ -1540,7 +1508,7 @@ static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd) | |||
1540 | * selection. | 1508 | * selection. |
1541 | */ | 1509 | */ |
1542 | 1510 | ||
1543 | timeout = jiffies + 25; | 1511 | timeout = jiffies + (250 * HZ / 1000); |
1544 | 1512 | ||
1545 | /* | 1513 | /* |
1546 | * XXX very interesting - we're seeing a bounce where the BSY we | 1514 | * XXX very interesting - we're seeing a bounce where the BSY we |
@@ -2123,9 +2091,8 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) | |||
2123 | * If the watchdog timer fires, all future | 2091 | * If the watchdog timer fires, all future |
2124 | * accesses to this device will use the | 2092 | * accesses to this device will use the |
2125 | * polled-IO. */ | 2093 | * polled-IO. */ |
2126 | printk(KERN_NOTICE "scsi%d: switching target %d " | 2094 | scmd_printk(KERN_INFO, cmd, |
2127 | "lun %llu to slow handshake\n", HOSTNO, | 2095 | "switching to slow handshake\n"); |
2128 | cmd->device->id, cmd->device->lun); | ||
2129 | cmd->device->borken = 1; | 2096 | cmd->device->borken = 1; |
2130 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | | 2097 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | |
2131 | ICR_ASSERT_ATN); | 2098 | ICR_ASSERT_ATN); |
@@ -2445,20 +2412,18 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) | |||
2445 | */ | 2412 | */ |
2446 | default: | 2413 | default: |
2447 | if (!tmp) { | 2414 | if (!tmp) { |
2448 | printk(KERN_DEBUG "scsi%d: rejecting message ", HOSTNO); | 2415 | printk(KERN_INFO "scsi%d: rejecting message ", |
2416 | instance->host_no); | ||
2449 | spi_print_msg(extended_msg); | 2417 | spi_print_msg(extended_msg); |
2450 | printk("\n"); | 2418 | printk("\n"); |
2451 | } else if (tmp != EXTENDED_MESSAGE) | 2419 | } else if (tmp != EXTENDED_MESSAGE) |
2452 | printk(KERN_DEBUG "scsi%d: rejecting unknown " | 2420 | scmd_printk(KERN_INFO, cmd, |
2453 | "message %02x from target %d, lun %llu\n", | 2421 | "rejecting unknown message %02x\n", |
2454 | HOSTNO, tmp, cmd->device->id, cmd->device->lun); | 2422 | tmp); |
2455 | else | 2423 | else |
2456 | printk(KERN_DEBUG "scsi%d: rejecting unknown " | 2424 | scmd_printk(KERN_INFO, cmd, |
2457 | "extended message " | 2425 | "rejecting unknown extended message code %02x, length %d\n", |
2458 | "code %02x, length %d from target %d, lun %llu\n", | 2426 | extended_msg[1], extended_msg[0]); |
2459 | HOSTNO, extended_msg[1], extended_msg[0], | ||
2460 | cmd->device->id, cmd->device->lun); | ||
2461 | |||
2462 | 2427 | ||
2463 | msgout = MESSAGE_REJECT; | 2428 | msgout = MESSAGE_REJECT; |
2464 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN); | 2429 | NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN); |