aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOndrej Zary <linux@rainbow-software.org>2015-02-06 17:11:55 -0500
committerJames Bottomley <JBottomley@Odin.com>2015-04-09 21:09:24 -0400
commit1b0224b0ec6003c06cc369188510642a5fb3b864 (patch)
treed01d88252ce202e7aa84aa1912d1b537c2d85865
parent764a0c7e840085828afbc16fb9b47be5712f5531 (diff)
aha1542: rework locking
Remove aha1542_lock and use host_lock instead. Remove interrupt and queuecommand function wrappers. Remove locking from lowlevel _out and _in functions, they now can onle be called (at runtime) with host_lock being held. Remove ssleep(4) in aha1542_reset as we can't sleep while holding a spinlock. It's useless anyway as wait_mask will wait until the controller is idle and kernel waits for 10 seconds (HOST_RESET_SETTLE_TIME) after that. Signed-off-by: Ondrej Zary <linux@rainbow-software.org> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: James Bottomley <JBottomley@Odin.com>
-rw-r--r--drivers/scsi/aha1542.c118
1 files changed, 34 insertions, 84 deletions
diff --git a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c
index a19fcb02ff20..7b5d396deaa5 100644
--- a/drivers/scsi/aha1542.c
+++ b/drivers/scsi/aha1542.c
@@ -62,8 +62,6 @@ struct aha1542_hostdata {
62 struct ccb ccb[AHA1542_MAILBOXES]; 62 struct ccb ccb[AHA1542_MAILBOXES];
63}; 63};
64 64
65static DEFINE_SPINLOCK(aha1542_lock);
66
67static inline void aha1542_intr_reset(u16 base) 65static inline void aha1542_intr_reset(u16 base)
68{ 66{
69 outb(IRST, CONTROL(base)); 67 outb(IRST, CONTROL(base));
@@ -91,41 +89,25 @@ static inline bool wait_mask(u16 port, u8 mask, u8 allof, u8 noneof, int timeout
91 return true; 89 return true;
92} 90}
93 91
94/* This is a bit complicated, but we need to make sure that an interrupt
95 routine does not send something out while we are in the middle of this.
96 Fortunately, it is only at boot time that multi-byte messages
97 are ever sent. */
98static int aha1542_outb(unsigned int base, u8 val) 92static int aha1542_outb(unsigned int base, u8 val)
99{ 93{
100 unsigned long flags;
101
102 while (1) { 94 while (1) {
103 if (!wait_mask(STATUS(base), CDF, 0, CDF, 0)) 95 if (!wait_mask(STATUS(base), CDF, 0, CDF, 0))
104 return 1; 96 return 1;
105 spin_lock_irqsave(&aha1542_lock, flags); 97 if (inb(STATUS(base)) & CDF)
106 if (inb(STATUS(base)) & CDF) {
107 spin_unlock_irqrestore(&aha1542_lock, flags);
108 continue; 98 continue;
109 }
110 outb(val, DATA(base)); 99 outb(val, DATA(base));
111 spin_unlock_irqrestore(&aha1542_lock, flags);
112 return 0; 100 return 0;
113 } 101 }
114} 102}
115 103
116static int aha1542_out(unsigned int base, u8 *buf, int len) 104static int aha1542_out(unsigned int base, u8 *buf, int len)
117{ 105{
118 unsigned long flags;
119
120 spin_lock_irqsave(&aha1542_lock, flags);
121 while (len--) { 106 while (len--) {
122 if (!wait_mask(STATUS(base), CDF, 0, CDF, 0)) { 107 if (!wait_mask(STATUS(base), CDF, 0, CDF, 0))
123 spin_unlock_irqrestore(&aha1542_lock, flags);
124 return 1; 108 return 1;
125 }
126 outb(*buf++, DATA(base)); 109 outb(*buf++, DATA(base));
127 } 110 }
128 spin_unlock_irqrestore(&aha1542_lock, flags);
129 if (!wait_mask(INTRFLAGS(base), INTRMASK, HACC, 0, 0)) 111 if (!wait_mask(INTRFLAGS(base), INTRMASK, HACC, 0, 0))
130 return 1; 112 return 1;
131 113
@@ -137,17 +119,11 @@ static int aha1542_out(unsigned int base, u8 *buf, int len)
137 119
138static int aha1542_in(unsigned int base, u8 *buf, int len, int timeout) 120static int aha1542_in(unsigned int base, u8 *buf, int len, int timeout)
139{ 121{
140 unsigned long flags;
141
142 spin_lock_irqsave(&aha1542_lock, flags);
143 while (len--) { 122 while (len--) {
144 if (!wait_mask(STATUS(base), DF, DF, 0, timeout)) { 123 if (!wait_mask(STATUS(base), DF, DF, 0, timeout))
145 spin_unlock_irqrestore(&aha1542_lock, flags);
146 return 1; 124 return 1;
147 }
148 *buf++ = inb(DATA(base)); 125 *buf++ = inb(DATA(base));
149 } 126 }
150 spin_unlock_irqrestore(&aha1542_lock, flags);
151 return 0; 127 return 0;
152} 128}
153 129
@@ -260,9 +236,9 @@ static int aha1542_test_port(struct Scsi_Host *sh)
260 return 1; 236 return 1;
261} 237}
262 238
263/* A "high" level interrupt handler */ 239static irqreturn_t aha1542_interrupt(int irq, void *dev_id)
264static void aha1542_intr_handle(struct Scsi_Host *sh)
265{ 240{
241 struct Scsi_Host *sh = dev_id;
266 struct aha1542_hostdata *aha1542 = shost_priv(sh); 242 struct aha1542_hostdata *aha1542 = shost_priv(sh);
267 void (*my_done)(struct scsi_cmnd *) = NULL; 243 void (*my_done)(struct scsi_cmnd *) = NULL;
268 int errstatus, mbi, mbo, mbistatus; 244 int errstatus, mbi, mbo, mbistatus;
@@ -292,7 +268,8 @@ static void aha1542_intr_handle(struct Scsi_Host *sh)
292#endif 268#endif
293 number_serviced = 0; 269 number_serviced = 0;
294 270
295 while (1 == 1) { 271 spin_lock_irqsave(sh->host_lock, flags);
272 while (1) {
296 flag = inb(INTRFLAGS(sh->io_port)); 273 flag = inb(INTRFLAGS(sh->io_port));
297 274
298 /* Check for unusual interrupts. If any of these happen, we should 275 /* Check for unusual interrupts. If any of these happen, we should
@@ -309,7 +286,6 @@ static void aha1542_intr_handle(struct Scsi_Host *sh)
309 } 286 }
310 aha1542_intr_reset(sh->io_port); 287 aha1542_intr_reset(sh->io_port);
311 288
312 spin_lock_irqsave(&aha1542_lock, flags);
313 mbi = aha1542->aha1542_last_mbi_used + 1; 289 mbi = aha1542->aha1542_last_mbi_used + 1;
314 if (mbi >= 2 * AHA1542_MAILBOXES) 290 if (mbi >= 2 * AHA1542_MAILBOXES)
315 mbi = AHA1542_MAILBOXES; 291 mbi = AHA1542_MAILBOXES;
@@ -323,18 +299,17 @@ static void aha1542_intr_handle(struct Scsi_Host *sh)
323 } while (mbi != aha1542->aha1542_last_mbi_used); 299 } while (mbi != aha1542->aha1542_last_mbi_used);
324 300
325 if (mb[mbi].status == 0) { 301 if (mb[mbi].status == 0) {
326 spin_unlock_irqrestore(&aha1542_lock, flags); 302 spin_unlock_irqrestore(sh->host_lock, flags);
327 /* Hmm, no mail. Must have read it the last time around */ 303 /* Hmm, no mail. Must have read it the last time around */
328 if (!number_serviced) 304 if (!number_serviced)
329 shost_printk(KERN_WARNING, sh, "interrupt received, but no mail.\n"); 305 shost_printk(KERN_WARNING, sh, "interrupt received, but no mail.\n");
330 return; 306 return IRQ_HANDLED;
331 }; 307 };
332 308
333 mbo = (scsi2int(mb[mbi].ccbptr) - (isa_virt_to_bus(&ccb[0]))) / sizeof(struct ccb); 309 mbo = (scsi2int(mb[mbi].ccbptr) - (isa_virt_to_bus(&ccb[0]))) / sizeof(struct ccb);
334 mbistatus = mb[mbi].status; 310 mbistatus = mb[mbi].status;
335 mb[mbi].status = 0; 311 mb[mbi].status = 0;
336 aha1542->aha1542_last_mbi_used = mbi; 312 aha1542->aha1542_last_mbi_used = mbi;
337 spin_unlock_irqrestore(&aha1542_lock, flags);
338 313
339#ifdef DEBUG 314#ifdef DEBUG
340 if (ccb[mbo].tarstat | ccb[mbo].hastat) 315 if (ccb[mbo].tarstat | ccb[mbo].hastat)
@@ -352,10 +327,11 @@ static void aha1542_intr_handle(struct Scsi_Host *sh)
352 tmp_cmd = aha1542->int_cmds[mbo]; 327 tmp_cmd = aha1542->int_cmds[mbo];
353 328
354 if (!tmp_cmd || !tmp_cmd->scsi_done) { 329 if (!tmp_cmd || !tmp_cmd->scsi_done) {
330 spin_unlock_irqrestore(sh->host_lock, flags);
355 shost_printk(KERN_WARNING, sh, "Unexpected interrupt\n"); 331 shost_printk(KERN_WARNING, sh, "Unexpected interrupt\n");
356 shost_printk(KERN_WARNING, sh, "tarstat=%x, hastat=%x idlun=%x ccb#=%d\n", ccb[mbo].tarstat, 332 shost_printk(KERN_WARNING, sh, "tarstat=%x, hastat=%x idlun=%x ccb#=%d\n", ccb[mbo].tarstat,
357 ccb[mbo].hastat, ccb[mbo].idlun, mbo); 333 ccb[mbo].hastat, ccb[mbo].idlun, mbo);
358 return; 334 return IRQ_HANDLED;
359 } 335 }
360 my_done = tmp_cmd->scsi_done; 336 my_done = tmp_cmd->scsi_done;
361 kfree(tmp_cmd->host_scribble); 337 kfree(tmp_cmd->host_scribble);
@@ -394,21 +370,8 @@ static void aha1542_intr_handle(struct Scsi_Host *sh)
394 }; 370 };
395} 371}
396 372
397/* A quick wrapper for do_aha1542_intr_handle to grab the spin lock */ 373static int aha1542_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *cmd)
398static irqreturn_t do_aha1542_intr_handle(int dummy, void *dev_id)
399{ 374{
400 unsigned long flags;
401 struct Scsi_Host *sh = dev_id;
402
403 spin_lock_irqsave(sh->host_lock, flags);
404 aha1542_intr_handle(sh);
405 spin_unlock_irqrestore(sh->host_lock, flags);
406 return IRQ_HANDLED;
407}
408
409static int aha1542_queuecommand_lck(struct scsi_cmnd *cmd, void (*done) (struct scsi_cmnd *))
410{
411 struct Scsi_Host *sh = cmd->device->host;
412 struct aha1542_hostdata *aha1542 = shost_priv(sh); 375 struct aha1542_hostdata *aha1542 = shost_priv(sh);
413 u8 direction; 376 u8 direction;
414 u8 target = cmd->device->id; 377 u8 target = cmd->device->id;
@@ -422,7 +385,7 @@ static int aha1542_queuecommand_lck(struct scsi_cmnd *cmd, void (*done) (struct
422 if (*cmd->cmnd == REQUEST_SENSE) { 385 if (*cmd->cmnd == REQUEST_SENSE) {
423 /* Don't do the command - we have the sense data already */ 386 /* Don't do the command - we have the sense data already */
424 cmd->result = 0; 387 cmd->result = 0;
425 done(cmd); 388 cmd->scsi_done(cmd);
426 return 0; 389 return 0;
427 } 390 }
428#ifdef DEBUG 391#ifdef DEBUG
@@ -440,7 +403,7 @@ static int aha1542_queuecommand_lck(struct scsi_cmnd *cmd, void (*done) (struct
440 /* Use the outgoing mailboxes in a round-robin fashion, because this 403 /* Use the outgoing mailboxes in a round-robin fashion, because this
441 is how the host adapter will scan for them */ 404 is how the host adapter will scan for them */
442 405
443 spin_lock_irqsave(&aha1542_lock, flags); 406 spin_lock_irqsave(sh->host_lock, flags);
444 mbo = aha1542->aha1542_last_mbo_used + 1; 407 mbo = aha1542->aha1542_last_mbo_used + 1;
445 if (mbo >= AHA1542_MAILBOXES) 408 if (mbo >= AHA1542_MAILBOXES)
446 mbo = 0; 409 mbo = 0;
@@ -460,10 +423,9 @@ static int aha1542_queuecommand_lck(struct scsi_cmnd *cmd, void (*done) (struct
460 screwing with this cdb. */ 423 screwing with this cdb. */
461 424
462 aha1542->aha1542_last_mbo_used = mbo; 425 aha1542->aha1542_last_mbo_used = mbo;
463 spin_unlock_irqrestore(&aha1542_lock, flags);
464 426
465#ifdef DEBUG 427#ifdef DEBUG
466 shost_printk(KERN_DEBUG, sh, "Sending command (%d %p)...", mbo, done); 428 shost_printk(KERN_DEBUG, sh, "Sending command (%d %p)...", mbo, cmd->scsi_done);
467#endif 429#endif
468 430
469 any2scsi(mb[mbo].ccbptr, isa_virt_to_bus(&ccb[mbo])); /* This gets trashed for some reason */ 431 any2scsi(mb[mbo].ccbptr, isa_virt_to_bus(&ccb[mbo])); /* This gets trashed for some reason */
@@ -492,6 +454,7 @@ static int aha1542_queuecommand_lck(struct scsi_cmnd *cmd, void (*done) (struct
492 if (cptr == NULL) { 454 if (cptr == NULL) {
493 /* free the claimed mailbox slot */ 455 /* free the claimed mailbox slot */
494 aha1542->int_cmds[mbo] = NULL; 456 aha1542->int_cmds[mbo] = NULL;
457 spin_unlock_irqrestore(sh->host_lock, flags);
495 return SCSI_MLQUEUE_HOST_BUSY; 458 return SCSI_MLQUEUE_HOST_BUSY;
496 } 459 }
497 scsi_for_each_sg(cmd, sg, sg_count, i) { 460 scsi_for_each_sg(cmd, sg, sg_count, i) {
@@ -518,23 +481,15 @@ static int aha1542_queuecommand_lck(struct scsi_cmnd *cmd, void (*done) (struct
518 481
519#ifdef DEBUG 482#ifdef DEBUG
520 print_hex_dump_bytes("sending: ", DUMP_PREFIX_NONE, &ccb[mbo], sizeof(ccb[mbo]) - 10); 483 print_hex_dump_bytes("sending: ", DUMP_PREFIX_NONE, &ccb[mbo], sizeof(ccb[mbo]) - 10);
484 printk("aha1542_queuecommand: now waiting for interrupt ");
521#endif 485#endif
522 486 mb[mbo].status = 1;
523 if (done) { 487 aha1542_outb(cmd->device->host->io_port, CMD_START_SCSI);
524#ifdef DEBUG 488 spin_unlock_irqrestore(sh->host_lock, flags);
525 printk("aha1542_queuecommand: now waiting for interrupt ");
526#endif
527 cmd->scsi_done = done;
528 mb[mbo].status = 1;
529 aha1542_outb(cmd->device->host->io_port, CMD_START_SCSI);
530 } else
531 printk("aha1542_queuecommand: done can't be NULL\n");
532 489
533 return 0; 490 return 0;
534} 491}
535 492
536static DEF_SCSI_QCMD(aha1542_queuecommand)
537
538/* Initialize mailboxes */ 493/* Initialize mailboxes */
539static void setup_mailboxes(struct Scsi_Host *sh) 494static void setup_mailboxes(struct Scsi_Host *sh)
540{ 495{
@@ -786,8 +741,7 @@ static struct Scsi_Host *aha1542_hw_init(struct scsi_host_template *tpnt, struct
786 741
787 setup_mailboxes(sh); 742 setup_mailboxes(sh);
788 743
789 if (request_irq(sh->irq, do_aha1542_intr_handle, 0, 744 if (request_irq(sh->irq, aha1542_interrupt, 0, "aha1542", sh)) {
790 "aha1542", sh)) {
791 shost_printk(KERN_ERR, sh, "Unable to allocate IRQ.\n"); 745 shost_printk(KERN_ERR, sh, "Unable to allocate IRQ.\n");
792 goto unregister; 746 goto unregister;
793 } 747 }
@@ -841,7 +795,8 @@ static int aha1542_release(struct Scsi_Host *sh)
841 */ 795 */
842static int aha1542_dev_reset(struct scsi_cmnd *cmd) 796static int aha1542_dev_reset(struct scsi_cmnd *cmd)
843{ 797{
844 struct aha1542_hostdata *aha1542 = shost_priv(cmd->device->host); 798 struct Scsi_Host *sh = cmd->device->host;
799 struct aha1542_hostdata *aha1542 = shost_priv(sh);
845 unsigned long flags; 800 unsigned long flags;
846 struct mailbox *mb = aha1542->mb; 801 struct mailbox *mb = aha1542->mb;
847 u8 target = cmd->device->id; 802 u8 target = cmd->device->id;
@@ -849,7 +804,7 @@ static int aha1542_dev_reset(struct scsi_cmnd *cmd)
849 int mbo; 804 int mbo;
850 struct ccb *ccb = aha1542->ccb; 805 struct ccb *ccb = aha1542->ccb;
851 806
852 spin_lock_irqsave(&aha1542_lock, flags); 807 spin_lock_irqsave(sh->host_lock, flags);
853 mbo = aha1542->aha1542_last_mbo_used + 1; 808 mbo = aha1542->aha1542_last_mbo_used + 1;
854 if (mbo >= AHA1542_MAILBOXES) 809 if (mbo >= AHA1542_MAILBOXES)
855 mbo = 0; 810 mbo = 0;
@@ -870,7 +825,6 @@ static int aha1542_dev_reset(struct scsi_cmnd *cmd)
870 screwing with this cdb. */ 825 screwing with this cdb. */
871 826
872 aha1542->aha1542_last_mbo_used = mbo; 827 aha1542->aha1542_last_mbo_used = mbo;
873 spin_unlock_irqrestore(&aha1542_lock, flags);
874 828
875 any2scsi(mb[mbo].ccbptr, isa_virt_to_bus(&ccb[mbo])); /* This gets trashed for some reason */ 829 any2scsi(mb[mbo].ccbptr, isa_virt_to_bus(&ccb[mbo])); /* This gets trashed for some reason */
876 830
@@ -887,7 +841,8 @@ static int aha1542_dev_reset(struct scsi_cmnd *cmd)
887 * Now tell the 1542 to flush all pending commands for this 841 * Now tell the 1542 to flush all pending commands for this
888 * target 842 * target
889 */ 843 */
890 aha1542_outb(cmd->device->host->io_port, CMD_START_SCSI); 844 aha1542_outb(sh->io_port, CMD_START_SCSI);
845 spin_unlock_irqrestore(sh->host_lock, flags);
891 846
892 scmd_printk(KERN_WARNING, cmd, 847 scmd_printk(KERN_WARNING, cmd,
893 "Trying device reset for target\n"); 848 "Trying device reset for target\n");
@@ -897,9 +852,12 @@ static int aha1542_dev_reset(struct scsi_cmnd *cmd)
897 852
898static int aha1542_reset(struct scsi_cmnd *cmd, u8 reset_cmd) 853static int aha1542_reset(struct scsi_cmnd *cmd, u8 reset_cmd)
899{ 854{
900 struct aha1542_hostdata *aha1542 = shost_priv(cmd->device->host); 855 struct Scsi_Host *sh = cmd->device->host;
856 struct aha1542_hostdata *aha1542 = shost_priv(sh);
857 unsigned long flags;
901 int i; 858 int i;
902 859
860 spin_lock_irqsave(sh->host_lock, flags);
903 /* 861 /*
904 * This does a scsi reset for all devices on the bus. 862 * This does a scsi reset for all devices on the bus.
905 * In principle, we could also reset the 1542 - should 863 * In principle, we could also reset the 1542 - should
@@ -908,27 +866,19 @@ static int aha1542_reset(struct scsi_cmnd *cmd, u8 reset_cmd)
908 */ 866 */
909 outb(reset_cmd, CONTROL(cmd->device->host->io_port)); 867 outb(reset_cmd, CONTROL(cmd->device->host->io_port));
910 868
911 /*
912 * Wait for the thing to settle down a bit. Unfortunately
913 * this is going to basically lock up the machine while we
914 * wait for this to complete. To be 100% correct, we need to
915 * check for timeout, and if we are doing something like this
916 * we are pretty desperate anyways.
917 */
918 ssleep(4);
919 spin_lock_irq(cmd->device->host->host_lock);
920
921 if (!wait_mask(STATUS(cmd->device->host->io_port), 869 if (!wait_mask(STATUS(cmd->device->host->io_port),
922 STATMASK, INIT | IDLE, STST | DIAGF | INVDCMD | DF | CDF, 0)) { 870 STATMASK, INIT | IDLE, STST | DIAGF | INVDCMD | DF | CDF, 0)) {
923 spin_unlock_irq(cmd->device->host->host_lock); 871 spin_unlock_irqrestore(sh->host_lock, flags);
924 return FAILED; 872 return FAILED;
925 } 873 }
874
926 /* 875 /*
927 * We need to do this too before the 1542 can interact with 876 * We need to do this too before the 1542 can interact with
928 * us again after host reset. 877 * us again after host reset.
929 */ 878 */
930 if (reset_cmd & HRST) 879 if (reset_cmd & HRST)
931 setup_mailboxes(cmd->device->host); 880 setup_mailboxes(cmd->device->host);
881
932 /* 882 /*
933 * Now try to pick up the pieces. For all pending commands, 883 * Now try to pick up the pieces. For all pending commands,
934 * free any internal data structures, and basically clear things 884 * free any internal data structures, and basically clear things
@@ -958,7 +908,7 @@ static int aha1542_reset(struct scsi_cmnd *cmd, u8 reset_cmd)
958 } 908 }
959 } 909 }
960 910
961 spin_unlock_irq(cmd->device->host->host_lock); 911 spin_unlock_irqrestore(sh->host_lock, flags);
962 return SUCCESS; 912 return SUCCESS;
963} 913}
964 914