1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76#include <scsi/scsi_dbg.h>
77#include <scsi/scsi_transport_spi.h>
78
79#if (NDEBUG & NDEBUG_LISTS)
80#define LIST(x, y) \
81 do { \
82 printk("LINE:%d Adding %p to %p\n", \
83 __LINE__, (void*)(x), (void*)(y)); \
84 if ((x) == (y)) \
85 udelay(5); \
86 } while (0)
87#define REMOVE(w, x, y, z) \
88 do { \
89 printk("LINE:%d Removing: %p->%p %p->%p \n", \
90 __LINE__, (void*)(w), (void*)(x), \
91 (void*)(y), (void*)(z)); \
92 if ((x) == (y)) \
93 udelay(5); \
94 } while (0)
95#else
96#define LIST(x,y)
97#define REMOVE(w,x,y,z)
98#endif
99
100#ifndef notyet
101#undef LINKED
102#endif
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266static struct Scsi_Host *first_instance = NULL;
267static struct scsi_host_template *the_template = NULL;
268
269
270#define SETUP_HOSTDATA(in) \
271 struct NCR5380_hostdata *hostdata = \
272 (struct NCR5380_hostdata *)(in)->hostdata
273#define HOSTDATA(in) ((struct NCR5380_hostdata *)(in)->hostdata)
274
275#define NEXT(cmd) ((Scsi_Cmnd *)(cmd)->host_scribble)
276#define SET_NEXT(cmd,next) ((cmd)->host_scribble = (void *)(next))
277#define NEXTADDR(cmd) ((Scsi_Cmnd **)&(cmd)->host_scribble)
278
279#define HOSTNO instance->host_no
280#define H_NO(cmd) (cmd)->device->host->host_no
281
282#ifdef SUPPORT_TAGS
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320#undef TAG_NONE
321#define TAG_NONE 0xff
322
323typedef struct {
324 DECLARE_BITMAP(allocated, MAX_TAGS);
325 int nr_allocated;
326 int queue_size;
327} TAG_ALLOC;
328
329static TAG_ALLOC TagAlloc[8][8];
330
331
332static void __init init_tags(void)
333{
334 int target, lun;
335 TAG_ALLOC *ta;
336
337 if (!setup_use_tagged_queuing)
338 return;
339
340 for (target = 0; target < 8; ++target) {
341 for (lun = 0; lun < 8; ++lun) {
342 ta = &TagAlloc[target][lun];
343 bitmap_zero(ta->allocated, MAX_TAGS);
344 ta->nr_allocated = 0;
345
346
347
348
349 ta->queue_size = MAX_TAGS;
350 }
351 }
352}
353
354
355
356
357
358
359
360
361
362static int is_lun_busy(Scsi_Cmnd *cmd, int should_be_tagged)
363{
364 SETUP_HOSTDATA(cmd->device->host);
365
366 if (hostdata->busy[cmd->device->id] & (1 << cmd->device->lun))
367 return 1;
368 if (!should_be_tagged ||
369 !setup_use_tagged_queuing || !cmd->device->tagged_supported)
370 return 0;
371 if (TagAlloc[cmd->device->id][cmd->device->lun].nr_allocated >=
372 TagAlloc[cmd->device->id][cmd->device->lun].queue_size) {
373 TAG_PRINTK("scsi%d: target %d lun %d: no free tags\n",
374 H_NO(cmd), cmd->device->id, cmd->device->lun);
375 return 1;
376 }
377 return 0;
378}
379
380
381
382
383
384
385
386static void cmd_get_tag(Scsi_Cmnd *cmd, int should_be_tagged)
387{
388 SETUP_HOSTDATA(cmd->device->host);
389
390
391
392
393 if (!should_be_tagged ||
394 !setup_use_tagged_queuing || !cmd->device->tagged_supported) {
395 cmd->tag = TAG_NONE;
396 hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);
397 TAG_PRINTK("scsi%d: target %d lun %d now allocated by untagged "
398 "command\n", H_NO(cmd), cmd->device->id, cmd->device->lun);
399 } else {
400 TAG_ALLOC *ta = &TagAlloc[cmd->device->id][cmd->device->lun];
401
402 cmd->tag = find_first_zero_bit(ta->allocated, MAX_TAGS);
403 set_bit(cmd->tag, ta->allocated);
404 ta->nr_allocated++;
405 TAG_PRINTK("scsi%d: using tag %d for target %d lun %d "
406 "(now %d tags in use)\n",
407 H_NO(cmd), cmd->tag, cmd->device->id,
408 cmd->device->lun, ta->nr_allocated);
409 }
410}
411
412
413
414
415
416
417static void cmd_free_tag(Scsi_Cmnd *cmd)
418{
419 SETUP_HOSTDATA(cmd->device->host);
420
421 if (cmd->tag == TAG_NONE) {
422 hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
423 TAG_PRINTK("scsi%d: target %d lun %d untagged cmd finished\n",
424 H_NO(cmd), cmd->device->id, cmd->device->lun);
425 } else if (cmd->tag >= MAX_TAGS) {
426 printk(KERN_NOTICE "scsi%d: trying to free bad tag %d!\n",
427 H_NO(cmd), cmd->tag);
428 } else {
429 TAG_ALLOC *ta = &TagAlloc[cmd->device->id][cmd->device->lun];
430 clear_bit(cmd->tag, ta->allocated);
431 ta->nr_allocated--;
432 TAG_PRINTK("scsi%d: freed tag %d for target %d lun %d\n",
433 H_NO(cmd), cmd->tag, cmd->device->id, cmd->device->lun);
434 }
435}
436
437
438static void free_all_tags(void)
439{
440 int target, lun;
441 TAG_ALLOC *ta;
442
443 if (!setup_use_tagged_queuing)
444 return;
445
446 for (target = 0; target < 8; ++target) {
447 for (lun = 0; lun < 8; ++lun) {
448 ta = &TagAlloc[target][lun];
449 bitmap_zero(ta->allocated, MAX_TAGS);
450 ta->nr_allocated = 0;
451 }
452 }
453}
454
455#endif
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470static void merge_contiguous_buffers(Scsi_Cmnd *cmd)
471{
472 unsigned long endaddr;
473#if (NDEBUG & NDEBUG_MERGING)
474 unsigned long oldlen = cmd->SCp.this_residual;
475 int cnt = 1;
476#endif
477
478 for (endaddr = virt_to_phys(cmd->SCp.ptr + cmd->SCp.this_residual - 1) + 1;
479 cmd->SCp.buffers_residual &&
480 virt_to_phys(sg_virt(&cmd->SCp.buffer[1])) == endaddr;) {
481 MER_PRINTK("VTOP(%p) == %08lx -> merging\n",
482 page_address(sg_page(&cmd->SCp.buffer[1])), endaddr);
483#if (NDEBUG & NDEBUG_MERGING)
484 ++cnt;
485#endif
486 ++cmd->SCp.buffer;
487 --cmd->SCp.buffers_residual;
488 cmd->SCp.this_residual += cmd->SCp.buffer->length;
489 endaddr += cmd->SCp.buffer->length;
490 }
491#if (NDEBUG & NDEBUG_MERGING)
492 if (oldlen != cmd->SCp.this_residual)
493 MER_PRINTK("merged %d buffers from %p, new length %08x\n",
494 cnt, cmd->SCp.ptr, cmd->SCp.this_residual);
495#endif
496}
497
498
499
500
501
502
503
504
505
506
507static inline void initialize_SCp(Scsi_Cmnd *cmd)
508{
509
510
511
512
513
514 if (scsi_bufflen(cmd)) {
515 cmd->SCp.buffer = scsi_sglist(cmd);
516 cmd->SCp.buffers_residual = scsi_sg_count(cmd) - 1;
517 cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
518 cmd->SCp.this_residual = cmd->SCp.buffer->length;
519
520
521
522 merge_contiguous_buffers(cmd);
523 } else {
524 cmd->SCp.buffer = NULL;
525 cmd->SCp.buffers_residual = 0;
526 cmd->SCp.ptr = NULL;
527 cmd->SCp.this_residual = 0;
528 }
529}
530
531#include <linux/delay.h>
532
533#if NDEBUG
534static struct {
535 unsigned char mask;
536 const char *name;
537} signals[] = {
538 { SR_DBP, "PARITY"}, { SR_RST, "RST" }, { SR_BSY, "BSY" },
539 { SR_REQ, "REQ" }, { SR_MSG, "MSG" }, { SR_CD, "CD" }, { SR_IO, "IO" },
540 { SR_SEL, "SEL" }, {0, NULL}
541}, basrs[] = {
542 {BASR_ATN, "ATN"}, {BASR_ACK, "ACK"}, {0, NULL}
543}, icrs[] = {
544 {ICR_ASSERT_RST, "ASSERT RST"},{ICR_ASSERT_ACK, "ASSERT ACK"},
545 {ICR_ASSERT_BSY, "ASSERT BSY"}, {ICR_ASSERT_SEL, "ASSERT SEL"},
546 {ICR_ASSERT_ATN, "ASSERT ATN"}, {ICR_ASSERT_DATA, "ASSERT DATA"},
547 {0, NULL}
548}, mrs[] = {
549 {MR_BLOCK_DMA_MODE, "MODE BLOCK DMA"}, {MR_TARGET, "MODE TARGET"},
550 {MR_ENABLE_PAR_CHECK, "MODE PARITY CHECK"}, {MR_ENABLE_PAR_INTR,
551 "MODE PARITY INTR"}, {MR_ENABLE_EOP_INTR,"MODE EOP INTR"},
552 {MR_MONITOR_BSY, "MODE MONITOR BSY"},
553 {MR_DMA_MODE, "MODE DMA"}, {MR_ARBITRATE, "MODE ARBITRATION"},
554 {0, NULL}
555};
556
557
558
559
560
561
562
563
564
565static void NCR5380_print(struct Scsi_Host *instance)
566{
567 unsigned char status, data, basr, mr, icr, i;
568 unsigned long flags;
569
570 local_irq_save(flags);
571 data = NCR5380_read(CURRENT_SCSI_DATA_REG);
572 status = NCR5380_read(STATUS_REG);
573 mr = NCR5380_read(MODE_REG);
574 icr = NCR5380_read(INITIATOR_COMMAND_REG);
575 basr = NCR5380_read(BUS_AND_STATUS_REG);
576 local_irq_restore(flags);
577 printk("STATUS_REG: %02x ", status);
578 for (i = 0; signals[i].mask; ++i)
579 if (status & signals[i].mask)
580 printk(",%s", signals[i].name);
581 printk("\nBASR: %02x ", basr);
582 for (i = 0; basrs[i].mask; ++i)
583 if (basr & basrs[i].mask)
584 printk(",%s", basrs[i].name);
585 printk("\nICR: %02x ", icr);
586 for (i = 0; icrs[i].mask; ++i)
587 if (icr & icrs[i].mask)
588 printk(",%s", icrs[i].name);
589 printk("\nMODE: %02x ", mr);
590 for (i = 0; mrs[i].mask; ++i)
591 if (mr & mrs[i].mask)
592 printk(",%s", mrs[i].name);
593 printk("\n");
594}
595
596static struct {
597 unsigned char value;
598 const char *name;
599} phases[] = {
600 {PHASE_DATAOUT, "DATAOUT"}, {PHASE_DATAIN, "DATAIN"}, {PHASE_CMDOUT, "CMDOUT"},
601 {PHASE_STATIN, "STATIN"}, {PHASE_MSGOUT, "MSGOUT"}, {PHASE_MSGIN, "MSGIN"},
602 {PHASE_UNKNOWN, "UNKNOWN"}
603};
604
605
606
607
608
609
610
611
612
613static void NCR5380_print_phase(struct Scsi_Host *instance)
614{
615 unsigned char status;
616 int i;
617
618 status = NCR5380_read(STATUS_REG);
619 if (!(status & SR_REQ))
620 printk(KERN_DEBUG "scsi%d: REQ not asserted, phase unknown.\n", HOSTNO);
621 else {
622 for (i = 0; (phases[i].value != PHASE_UNKNOWN) &&
623 (phases[i].value != (status & PHASE_MASK)); ++i)
624 ;
625 printk(KERN_DEBUG "scsi%d: phase %s\n", HOSTNO, phases[i].name);
626 }
627}
628
629#else
630
631
632static inline void NCR5380_print(struct Scsi_Host *instance)
633{
634};
635static inline void NCR5380_print_phase(struct Scsi_Host *instance)
636{
637};
638
639#endif
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654#include <linux/gfp.h>
655#include <linux/workqueue.h>
656#include <linux/interrupt.h>
657
658static volatile int main_running;
659static DECLARE_WORK(NCR5380_tqueue, NCR5380_main);
660
661static inline void queue_main(void)
662{
663 if (!main_running) {
664
665
666
667
668 schedule_work(&NCR5380_tqueue);
669 }
670
671
672}
673
674
675static inline void NCR5380_all_init(void)
676{
677 static int done = 0;
678 if (!done) {
679 INI_PRINTK("scsi : NCR5380_all_init()\n");
680 done = 1;
681 }
682}
683
684
685
686
687
688
689
690
691
692
693
694static void __init NCR5380_print_options(struct Scsi_Host *instance)
695{
696 printk(" generic options"
697#ifdef AUTOSENSE
698 " AUTOSENSE"
699#endif
700#ifdef REAL_DMA
701 " REAL DMA"
702#endif
703#ifdef PARITY
704 " PARITY"
705#endif
706#ifdef SUPPORT_TAGS
707 " SCSI-2 TAGGED QUEUING"
708#endif
709 );
710 printk(" generic release=%d", NCR5380_PUBLIC_RELEASE);
711}
712
713
714
715
716
717
718
719
720
721
722static void lprint_Scsi_Cmnd(Scsi_Cmnd *cmd)
723{
724 int i, s;
725 unsigned char *command;
726 printk("scsi%d: destination target %d, lun %d\n",
727 H_NO(cmd), cmd->device->id, cmd->device->lun);
728 printk(KERN_CONT " command = ");
729 command = cmd->cmnd;
730 printk(KERN_CONT "%2d (0x%02x)", command[0], command[0]);
731 for (i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i)
732 printk(KERN_CONT " %02x", command[i]);
733 printk("\n");
734}
735
736static void NCR5380_print_status(struct Scsi_Host *instance)
737{
738 struct NCR5380_hostdata *hostdata;
739 Scsi_Cmnd *ptr;
740 unsigned long flags;
741
742 NCR_PRINT(NDEBUG_ANY);
743 NCR_PRINT_PHASE(NDEBUG_ANY);
744
745 hostdata = (struct NCR5380_hostdata *)instance->hostdata;
746
747 printk("\nNCR5380 core release=%d.\n", NCR5380_PUBLIC_RELEASE);
748 local_irq_save(flags);
749 printk("NCR5380: coroutine is%s running.\n",
750 main_running ? "" : "n't");
751 if (!hostdata->connected)
752 printk("scsi%d: no currently connected command\n", HOSTNO);
753 else
754 lprint_Scsi_Cmnd((Scsi_Cmnd *) hostdata->connected);
755 printk("scsi%d: issue_queue\n", HOSTNO);
756 for (ptr = (Scsi_Cmnd *)hostdata->issue_queue; ptr; ptr = NEXT(ptr))
757 lprint_Scsi_Cmnd(ptr);
758
759 printk("scsi%d: disconnected_queue\n", HOSTNO);
760 for (ptr = (Scsi_Cmnd *) hostdata->disconnected_queue; ptr;
761 ptr = NEXT(ptr))
762 lprint_Scsi_Cmnd(ptr);
763
764 local_irq_restore(flags);
765 printk("\n");
766}
767
768static void show_Scsi_Cmnd(Scsi_Cmnd *cmd, struct seq_file *m)
769{
770 int i, s;
771 unsigned char *command;
772 seq_printf(m, "scsi%d: destination target %d, lun %d\n",
773 H_NO(cmd), cmd->device->id, cmd->device->lun);
774 seq_printf(m, " command = ");
775 command = cmd->cmnd;
776 seq_printf(m, "%2d (0x%02x)", command[0], command[0]);
777 for (i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i)
778 seq_printf(m, " %02x", command[i]);
779 seq_printf(m, "\n");
780}
781
782static int NCR5380_show_info(struct seq_file *m, struct Scsi_Host *instance)
783{
784 struct NCR5380_hostdata *hostdata;
785 Scsi_Cmnd *ptr;
786 unsigned long flags;
787
788 hostdata = (struct NCR5380_hostdata *)instance->hostdata;
789
790 seq_printf(m, "NCR5380 core release=%d.\n", NCR5380_PUBLIC_RELEASE);
791 local_irq_save(flags);
792 seq_printf(m, "NCR5380: coroutine is%s running.\n",
793 main_running ? "" : "n't");
794 if (!hostdata->connected)
795 seq_printf(m, "scsi%d: no currently connected command\n", HOSTNO);
796 else
797 show_Scsi_Cmnd((Scsi_Cmnd *) hostdata->connected, m);
798 seq_printf(m, "scsi%d: issue_queue\n", HOSTNO);
799 for (ptr = (Scsi_Cmnd *)hostdata->issue_queue; ptr; ptr = NEXT(ptr))
800 show_Scsi_Cmnd(ptr, m);
801
802 seq_printf(m, "scsi%d: disconnected_queue\n", HOSTNO);
803 for (ptr = (Scsi_Cmnd *) hostdata->disconnected_queue; ptr;
804 ptr = NEXT(ptr))
805 show_Scsi_Cmnd(ptr, m);
806
807 local_irq_restore(flags);
808 return 0;
809}
810
811
812
813
814
815
816
817
818
819
820
821
822
823static int __init NCR5380_init(struct Scsi_Host *instance, int flags)
824{
825 int i;
826 SETUP_HOSTDATA(instance);
827
828 NCR5380_all_init();
829
830 hostdata->aborted = 0;
831 hostdata->id_mask = 1 << instance->this_id;
832 hostdata->id_higher_mask = 0;
833 for (i = hostdata->id_mask; i <= 0x80; i <<= 1)
834 if (i > hostdata->id_mask)
835 hostdata->id_higher_mask |= i;
836 for (i = 0; i < 8; ++i)
837 hostdata->busy[i] = 0;
838#ifdef SUPPORT_TAGS
839 init_tags();
840#endif
841#if defined (REAL_DMA)
842 hostdata->dma_len = 0;
843#endif
844 hostdata->targets_present = 0;
845 hostdata->connected = NULL;
846 hostdata->issue_queue = NULL;
847 hostdata->disconnected_queue = NULL;
848 hostdata->flags = FLAG_CHECK_LAST_BYTE_SENT;
849
850 if (!the_template) {
851 the_template = instance->hostt;
852 first_instance = instance;
853 }
854
855#ifndef AUTOSENSE
856 if ((instance->cmd_per_lun > 1) || (instance->can_queue > 1))
857 printk("scsi%d: WARNING : support for multiple outstanding commands enabled\n"
858 " without AUTOSENSE option, contingent allegiance conditions may\n"
859 " be incorrectly cleared.\n", HOSTNO);
860#endif
861
862 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
863 NCR5380_write(MODE_REG, MR_BASE);
864 NCR5380_write(TARGET_COMMAND_REG, 0);
865 NCR5380_write(SELECT_ENABLE_REG, 0);
866
867 return 0;
868}
869
870static void NCR5380_exit(struct Scsi_Host *instance)
871{
872
873}
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893static int NCR5380_queue_command_lck(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
894{
895 SETUP_HOSTDATA(cmd->device->host);
896 Scsi_Cmnd *tmp;
897 unsigned long flags;
898
899#if (NDEBUG & NDEBUG_NO_WRITE)
900 switch (cmd->cmnd[0]) {
901 case WRITE_6:
902 case WRITE_10:
903 printk(KERN_NOTICE "scsi%d: WRITE attempted with NO_WRITE debugging flag set\n",
904 H_NO(cmd));
905 cmd->result = (DID_ERROR << 16);
906 done(cmd);
907 return 0;
908 }
909#endif
910
911#ifdef NCR5380_STATS
912# if 0
913 if (!hostdata->connected && !hostdata->issue_queue &&
914 !hostdata->disconnected_queue) {
915 hostdata->timebase = jiffies;
916 }
917# endif
918# ifdef NCR5380_STAT_LIMIT
919 if (scsi_bufflen(cmd) > NCR5380_STAT_LIMIT)
920# endif
921 switch (cmd->cmnd[0]) {
922 case WRITE:
923 case WRITE_6:
924 case WRITE_10:
925 hostdata->time_write[cmd->device->id] -= (jiffies - hostdata->timebase);
926 hostdata->bytes_write[cmd->device->id] += scsi_bufflen(cmd);
927 hostdata->pendingw++;
928 break;
929 case READ:
930 case READ_6:
931 case READ_10:
932 hostdata->time_read[cmd->device->id] -= (jiffies - hostdata->timebase);
933 hostdata->bytes_read[cmd->device->id] += scsi_bufflen(cmd);
934 hostdata->pendingr++;
935 break;
936 }
937#endif
938
939
940
941
942
943
944 SET_NEXT(cmd, NULL);
945 cmd->scsi_done = done;
946
947 cmd->result = 0;
948
949
950
951
952
953
954
955
956 local_irq_save(flags);
957
958
959
960
961
962
963
964
965
966
967
968
969 if (!IS_A_TT()) {
970
971 falcon_get_lock();
972
973 }
974 if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) {
975 LIST(cmd, hostdata->issue_queue);
976 SET_NEXT(cmd, hostdata->issue_queue);
977 hostdata->issue_queue = cmd;
978 } else {
979 for (tmp = (Scsi_Cmnd *)hostdata->issue_queue;
980 NEXT(tmp); tmp = NEXT(tmp))
981 ;
982 LIST(cmd, tmp);
983 SET_NEXT(tmp, cmd);
984 }
985 local_irq_restore(flags);
986
987 QU_PRINTK("scsi%d: command added to %s of queue\n", H_NO(cmd),
988 (cmd->cmnd[0] == REQUEST_SENSE) ? "head" : "tail");
989
990
991
992
993
994
995
996
997 if (in_interrupt() || ((flags >> 8) & 7) >= 6)
998 queue_main();
999 else
1000 NCR5380_main(NULL);
1001 return 0;
1002}
1003
1004static DEF_SCSI_QCMD(NCR5380_queue_command)
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018static void NCR5380_main(struct work_struct *work)
1019{
1020 Scsi_Cmnd *tmp, *prev;
1021 struct Scsi_Host *instance = first_instance;
1022 struct NCR5380_hostdata *hostdata = HOSTDATA(instance);
1023 int done;
1024 unsigned long flags;
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047 if (main_running)
1048 return;
1049 main_running = 1;
1050
1051 local_save_flags(flags);
1052 do {
1053 local_irq_disable();
1054 done = 1;
1055
1056 if (!hostdata->connected) {
1057 MAIN_PRINTK("scsi%d: not connected\n", HOSTNO);
1058
1059
1060
1061
1062#if (NDEBUG & NDEBUG_LISTS)
1063 for (tmp = (Scsi_Cmnd *) hostdata->issue_queue, prev = NULL;
1064 tmp && (tmp != prev); prev = tmp, tmp = NEXT(tmp))
1065 ;
1066
1067 if ((tmp == prev) && tmp)
1068 printk(" LOOP\n");
1069
1070#endif
1071 for (tmp = (Scsi_Cmnd *) hostdata->issue_queue,
1072 prev = NULL; tmp; prev = tmp, tmp = NEXT(tmp)) {
1073
1074#if (NDEBUG & NDEBUG_LISTS)
1075 if (prev != tmp)
1076 printk("MAIN tmp=%p target=%d busy=%d lun=%d\n",
1077 tmp, tmp->device->id, hostdata->busy[tmp->device->id],
1078 tmp->device->lun);
1079#endif
1080
1081
1082 if (
1083#ifdef SUPPORT_TAGS
1084 !is_lun_busy( tmp, tmp->cmnd[0] != REQUEST_SENSE)
1085#else
1086 !(hostdata->busy[tmp->device->id] & (1 << tmp->device->lun))
1087#endif
1088 ) {
1089
1090 local_irq_disable();
1091 if (prev) {
1092 REMOVE(prev, NEXT(prev), tmp, NEXT(tmp));
1093 SET_NEXT(prev, NEXT(tmp));
1094 } else {
1095 REMOVE(-1, hostdata->issue_queue, tmp, NEXT(tmp));
1096 hostdata->issue_queue = NEXT(tmp);
1097 }
1098 SET_NEXT(tmp, NULL);
1099 falcon_dont_release++;
1100
1101
1102 local_irq_restore(flags);
1103
1104
1105
1106
1107
1108
1109
1110 MAIN_PRINTK("scsi%d: main(): command for target %d "
1111 "lun %d removed from issue_queue\n",
1112 HOSTNO, tmp->device->id, tmp->device->lun);
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123#ifdef SUPPORT_TAGS
1124 cmd_get_tag(tmp, tmp->cmnd[0] != REQUEST_SENSE);
1125#endif
1126 if (!NCR5380_select(instance, tmp,
1127 (tmp->cmnd[0] == REQUEST_SENSE) ? TAG_NONE :
1128 TAG_NEXT)) {
1129 falcon_dont_release--;
1130
1131 falcon_release_lock_if_possible(hostdata);
1132 break;
1133 } else {
1134 local_irq_disable();
1135 LIST(tmp, hostdata->issue_queue);
1136 SET_NEXT(tmp, hostdata->issue_queue);
1137 hostdata->issue_queue = tmp;
1138#ifdef SUPPORT_TAGS
1139 cmd_free_tag(tmp);
1140#endif
1141 falcon_dont_release--;
1142 local_irq_restore(flags);
1143 MAIN_PRINTK("scsi%d: main(): select() failed, "
1144 "returned to issue_queue\n", HOSTNO);
1145 if (hostdata->connected)
1146 break;
1147 }
1148 }
1149 }
1150 }
1151
1152 if (hostdata->connected
1153#ifdef REAL_DMA
1154 && !hostdata->dma_len
1155#endif
1156 ) {
1157 local_irq_restore(flags);
1158 MAIN_PRINTK("scsi%d: main: performing information transfer\n",
1159 HOSTNO);
1160 NCR5380_information_transfer(instance);
1161 MAIN_PRINTK("scsi%d: main: done set false\n", HOSTNO);
1162 done = 0;
1163 }
1164 } while (!done);
1165
1166
1167
1168
1169 main_running = 0;
1170 local_irq_restore(flags);
1171}
1172
1173
1174#ifdef REAL_DMA
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185static void NCR5380_dma_complete(struct Scsi_Host *instance)
1186{
1187 SETUP_HOSTDATA(instance);
1188 int transfered, saved_data = 0, overrun = 0, cnt, toPIO;
1189 unsigned char **data, p;
1190 volatile int *count;
1191
1192 if (!hostdata->connected) {
1193 printk(KERN_WARNING "scsi%d: received end of DMA interrupt with "
1194 "no connected cmd\n", HOSTNO);
1195 return;
1196 }
1197
1198 if (atari_read_overruns) {
1199 p = hostdata->connected->SCp.phase;
1200 if (p & SR_IO) {
1201 udelay(10);
1202 if ((NCR5380_read(BUS_AND_STATUS_REG) &
1203 (BASR_PHASE_MATCH|BASR_ACK)) ==
1204 (BASR_PHASE_MATCH|BASR_ACK)) {
1205 saved_data = NCR5380_read(INPUT_DATA_REG);
1206 overrun = 1;
1207 DMA_PRINTK("scsi%d: read overrun handled\n", HOSTNO);
1208 }
1209 }
1210 }
1211
1212 DMA_PRINTK("scsi%d: real DMA transfer complete, basr 0x%X, sr 0x%X\n",
1213 HOSTNO, NCR5380_read(BUS_AND_STATUS_REG),
1214 NCR5380_read(STATUS_REG));
1215
1216 (void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
1217 NCR5380_write(MODE_REG, MR_BASE);
1218 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
1219
1220 transfered = hostdata->dma_len - NCR5380_dma_residual(instance);
1221 hostdata->dma_len = 0;
1222
1223 data = (unsigned char **)&hostdata->connected->SCp.ptr;
1224 count = &hostdata->connected->SCp.this_residual;
1225 *data += transfered;
1226 *count -= transfered;
1227
1228 if (atari_read_overruns) {
1229 if ((NCR5380_read(STATUS_REG) & PHASE_MASK) == p && (p & SR_IO)) {
1230 cnt = toPIO = atari_read_overruns;
1231 if (overrun) {
1232 DMA_PRINTK("Got an input overrun, using saved byte\n");
1233 *(*data)++ = saved_data;
1234 (*count)--;
1235 cnt--;
1236 toPIO--;
1237 }
1238 DMA_PRINTK("Doing %d-byte PIO to 0x%08lx\n", cnt, (long)*data);
1239 NCR5380_transfer_pio(instance, &p, &cnt, data);
1240 *count -= toPIO - cnt;
1241 }
1242 }
1243}
1244#endif
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258static irqreturn_t NCR5380_intr(int irq, void *dev_id)
1259{
1260 struct Scsi_Host *instance = first_instance;
1261 int done = 1, handled = 0;
1262 unsigned char basr;
1263
1264 INT_PRINTK("scsi%d: NCR5380 irq triggered\n", HOSTNO);
1265
1266
1267 basr = NCR5380_read(BUS_AND_STATUS_REG);
1268 INT_PRINTK("scsi%d: BASR=%02x\n", HOSTNO, basr);
1269
1270 if (basr & BASR_IRQ) {
1271 NCR_PRINT(NDEBUG_INTR);
1272 if ((NCR5380_read(STATUS_REG) & (SR_SEL|SR_IO)) == (SR_SEL|SR_IO)) {
1273 done = 0;
1274 ENABLE_IRQ();
1275 INT_PRINTK("scsi%d: SEL interrupt\n", HOSTNO);
1276 NCR5380_reselect(instance);
1277 (void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
1278 } else if (basr & BASR_PARITY_ERROR) {
1279 INT_PRINTK("scsi%d: PARITY interrupt\n", HOSTNO);
1280 (void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
1281 } else if ((NCR5380_read(STATUS_REG) & SR_RST) == SR_RST) {
1282 INT_PRINTK("scsi%d: RESET interrupt\n", HOSTNO);
1283 (void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
1284 } else {
1285
1286
1287
1288
1289
1290#if defined(REAL_DMA)
1291
1292
1293
1294
1295
1296
1297 if ((NCR5380_read(MODE_REG) & MR_DMA_MODE) &&
1298 ((basr & BASR_END_DMA_TRANSFER) ||
1299 !(basr & BASR_PHASE_MATCH))) {
1300
1301 INT_PRINTK("scsi%d: PHASE MISM or EOP interrupt\n", HOSTNO);
1302 NCR5380_dma_complete( instance );
1303 done = 0;
1304 ENABLE_IRQ();
1305 } else
1306#endif
1307 {
1308
1309 if (basr & BASR_PHASE_MATCH)
1310 printk(KERN_NOTICE "scsi%d: unknown interrupt, "
1311 "BASR 0x%x, MR 0x%x, SR 0x%x\n",
1312 HOSTNO, basr, NCR5380_read(MODE_REG),
1313 NCR5380_read(STATUS_REG));
1314 (void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
1315 }
1316 }
1317 handled = 1;
1318 } else {
1319 printk(KERN_NOTICE "scsi%d: interrupt without IRQ bit set in BASR, "
1320 "BASR 0x%X, MR 0x%X, SR 0x%x\n", HOSTNO, basr,
1321 NCR5380_read(MODE_REG), NCR5380_read(STATUS_REG));
1322 (void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
1323 }
1324
1325 if (!done) {
1326 INT_PRINTK("scsi%d: in int routine, calling main\n", HOSTNO);
1327
1328 queue_main();
1329 }
1330 return IRQ_RETVAL(handled);
1331}
1332
1333#ifdef NCR5380_STATS
1334static void collect_stats(struct NCR5380_hostdata* hostdata, Scsi_Cmnd *cmd)
1335{
1336# ifdef NCR5380_STAT_LIMIT
1337 if (scsi_bufflen(cmd) > NCR5380_STAT_LIMIT)
1338# endif
1339 switch (cmd->cmnd[0]) {
1340 case WRITE:
1341 case WRITE_6:
1342 case WRITE_10:
1343 hostdata->time_write[cmd->device->id] += (jiffies - hostdata->timebase);
1344
1345 hostdata->pendingw--;
1346 break;
1347 case READ:
1348 case READ_6:
1349 case READ_10:
1350 hostdata->time_read[cmd->device->id] += (jiffies - hostdata->timebase);
1351
1352 hostdata->pendingr--;
1353 break;
1354 }
1355}
1356#endif
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd *cmd, int tag)
1390{
1391 SETUP_HOSTDATA(instance);
1392 unsigned char tmp[3], phase;
1393 unsigned char *data;
1394 int len;
1395 unsigned long timeout;
1396 unsigned long flags;
1397
1398 hostdata->restart_select = 0;
1399 NCR_PRINT(NDEBUG_ARBITRATION);
1400 ARB_PRINTK("scsi%d: starting arbitration, id = %d\n", HOSTNO,
1401 instance->this_id);
1402
1403
1404
1405
1406
1407
1408 local_irq_save(flags);
1409 if (hostdata->connected) {
1410 local_irq_restore(flags);
1411 return -1;
1412 }
1413 NCR5380_write(TARGET_COMMAND_REG, 0);
1414
1415
1416
1417
1418
1419 NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask);
1420 NCR5380_write(MODE_REG, MR_ARBITRATE);
1421
1422 local_irq_restore(flags);
1423
1424
1425#if defined(NCR_TIMEOUT)
1426 {
1427 unsigned long timeout = jiffies + 2*NCR_TIMEOUT;
1428
1429 while (!(NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_PROGRESS) &&
1430 time_before(jiffies, timeout) && !hostdata->connected)
1431 ;
1432 if (time_after_eq(jiffies, timeout)) {
1433 printk("scsi : arbitration timeout at %d\n", __LINE__);
1434 NCR5380_write(MODE_REG, MR_BASE);
1435 NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
1436 return -1;
1437 }
1438 }
1439#else
1440 while (!(NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_PROGRESS) &&
1441 !hostdata->connected)
1442 ;
1443#endif
1444
1445 ARB_PRINTK("scsi%d: arbitration complete\n", HOSTNO);
1446
1447 if (hostdata->connected) {
1448 NCR5380_write(MODE_REG, MR_BASE);
1449 return -1;
1450 }
1451
1452
1453
1454
1455
1456
1457
1458 udelay(3);
1459
1460
1461 if ((NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) ||
1462 (NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_higher_mask) ||
1463 (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) ||
1464 hostdata->connected) {
1465 NCR5380_write(MODE_REG, MR_BASE);
1466 ARB_PRINTK("scsi%d: lost arbitration, deasserting MR_ARBITRATE\n",
1467 HOSTNO);
1468 return -1;
1469 }
1470
1471
1472
1473
1474 NCR5380_write(INITIATOR_COMMAND_REG,
1475 ICR_BASE | ICR_ASSERT_SEL | ICR_ASSERT_BSY);
1476
1477 if ((NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) ||
1478 hostdata->connected) {
1479 NCR5380_write(MODE_REG, MR_BASE);
1480 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
1481 ARB_PRINTK("scsi%d: lost arbitration, deasserting ICR_ASSERT_SEL\n",
1482 HOSTNO);
1483 return -1;
1484 }
1485
1486
1487
1488
1489
1490
1491#ifdef CONFIG_ATARI_SCSI_TOSHIBA_DELAY
1492
1493 udelay(15);
1494#else
1495 udelay(2);
1496#endif
1497
1498 if (hostdata->connected) {
1499 NCR5380_write(MODE_REG, MR_BASE);
1500 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
1501 return -1;
1502 }
1503
1504 ARB_PRINTK("scsi%d: won arbitration\n", HOSTNO);
1505
1506
1507
1508
1509
1510
1511 NCR5380_write(OUTPUT_DATA_REG, (hostdata->id_mask | (1 << cmd->device->id)));
1512
1513
1514
1515
1516
1517
1518
1519 NCR5380_write(INITIATOR_COMMAND_REG, (ICR_BASE | ICR_ASSERT_BSY |
1520 ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_SEL ));
1521 NCR5380_write(MODE_REG, MR_BASE);
1522
1523
1524
1525
1526
1527
1528 if (hostdata->connected) {
1529 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
1530 return -1;
1531 }
1532
1533 NCR5380_write(SELECT_ENABLE_REG, 0);
1534
1535
1536
1537
1538
1539 udelay(1);
1540
1541
1542 NCR5380_write(INITIATOR_COMMAND_REG, (ICR_BASE | ICR_ASSERT_DATA |
1543 ICR_ASSERT_ATN | ICR_ASSERT_SEL));
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562 udelay(1);
1563
1564 SEL_PRINTK("scsi%d: selecting target %d\n", HOSTNO, cmd->device->id);
1565
1566
1567
1568
1569
1570
1571 timeout = jiffies + 25;
1572
1573
1574
1575
1576
1577
1578
1579#if 0
1580
1581
1582
1583
1584
1585
1586
1587 while (time_before(jiffies, timeout) &&
1588 !(NCR5380_read(STATUS_REG) & (SR_BSY | SR_IO)))
1589 ;
1590
1591 if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) == (SR_SEL | SR_IO)) {
1592 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
1593 NCR5380_reselect(instance);
1594 printk(KERN_ERR "scsi%d: reselection after won arbitration?\n",
1595 HOSTNO);
1596 NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
1597 return -1;
1598 }
1599#else
1600 while (time_before(jiffies, timeout) && !(NCR5380_read(STATUS_REG) & SR_BSY))
1601 ;
1602#endif
1603
1604
1605
1606
1607
1608
1609
1610 udelay(1);
1611
1612 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
1613
1614 if (!(NCR5380_read(STATUS_REG) & SR_BSY)) {
1615 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
1616 if (hostdata->targets_present & (1 << cmd->device->id)) {
1617 printk(KERN_ERR "scsi%d: weirdness\n", HOSTNO);
1618 if (hostdata->restart_select)
1619 printk(KERN_NOTICE "\trestart select\n");
1620 NCR_PRINT(NDEBUG_ANY);
1621 NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
1622 return -1;
1623 }
1624 cmd->result = DID_BAD_TARGET << 16;
1625#ifdef NCR5380_STATS
1626 collect_stats(hostdata, cmd);
1627#endif
1628#ifdef SUPPORT_TAGS
1629 cmd_free_tag(cmd);
1630#endif
1631 cmd->scsi_done(cmd);
1632 NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
1633 SEL_PRINTK("scsi%d: target did not respond within 250ms\n", HOSTNO);
1634 NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
1635 return 0;
1636 }
1637
1638 hostdata->targets_present |= (1 << cmd->device->id);
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656 while (!(NCR5380_read(STATUS_REG) & SR_REQ))
1657 ;
1658
1659 SEL_PRINTK("scsi%d: target %d selected, going into MESSAGE OUT phase.\n",
1660 HOSTNO, cmd->device->id);
1661 tmp[0] = IDENTIFY(1, cmd->device->lun);
1662
1663#ifdef SUPPORT_TAGS
1664 if (cmd->tag != TAG_NONE) {
1665 tmp[1] = hostdata->last_message = SIMPLE_QUEUE_TAG;
1666 tmp[2] = cmd->tag;
1667 len = 3;
1668 } else
1669 len = 1;
1670#else
1671 len = 1;
1672 cmd->tag = 0;
1673#endif
1674
1675
1676 data = tmp;
1677 phase = PHASE_MSGOUT;
1678 NCR5380_transfer_pio(instance, &phase, &len, &data);
1679 SEL_PRINTK("scsi%d: nexus established.\n", HOSTNO);
1680
1681 hostdata->connected = cmd;
1682#ifndef SUPPORT_TAGS
1683 hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);
1684#endif
1685
1686 initialize_SCp(cmd);
1687
1688 return 0;
1689}
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716static int NCR5380_transfer_pio(struct Scsi_Host *instance,
1717 unsigned char *phase, int *count,
1718 unsigned char **data)
1719{
1720 register unsigned char p = *phase, tmp;
1721 register int c = *count;
1722 register unsigned char *d = *data;
1723
1724
1725
1726
1727
1728
1729
1730 NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p));
1731
1732 do {
1733
1734
1735
1736
1737 while (!((tmp = NCR5380_read(STATUS_REG)) & SR_REQ))
1738 ;
1739
1740 HSH_PRINTK("scsi%d: REQ detected\n", HOSTNO);
1741
1742
1743 if ((tmp & PHASE_MASK) != p) {
1744 PIO_PRINTK("scsi%d: phase mismatch\n", HOSTNO);
1745 NCR_PRINT_PHASE(NDEBUG_PIO);
1746 break;
1747 }
1748
1749
1750 if (!(p & SR_IO))
1751 NCR5380_write(OUTPUT_DATA_REG, *d);
1752 else
1753 *d = NCR5380_read(CURRENT_SCSI_DATA_REG);
1754
1755 ++d;
1756
1757
1758
1759
1760
1761
1762
1763
1764 if (!(p & SR_IO)) {
1765 if (!((p & SR_MSG) && c > 1)) {
1766 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA);
1767 NCR_PRINT(NDEBUG_PIO);
1768 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
1769 ICR_ASSERT_DATA | ICR_ASSERT_ACK);
1770 } else {
1771 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
1772 ICR_ASSERT_DATA | ICR_ASSERT_ATN);
1773 NCR_PRINT(NDEBUG_PIO);
1774 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
1775 ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_ACK);
1776 }
1777 } else {
1778 NCR_PRINT(NDEBUG_PIO);
1779 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ACK);
1780 }
1781
1782 while (NCR5380_read(STATUS_REG) & SR_REQ)
1783 ;
1784
1785 HSH_PRINTK("scsi%d: req false, handshake complete\n", HOSTNO);
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798 if (!(p == PHASE_MSGIN && c == 1)) {
1799 if (p == PHASE_MSGOUT && c > 1)
1800 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
1801 else
1802 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
1803 }
1804 } while (--c);
1805
1806 PIO_PRINTK("scsi%d: residual %d\n", HOSTNO, c);
1807
1808 *count = c;
1809 *data = d;
1810 tmp = NCR5380_read(STATUS_REG);
1811
1812
1813
1814
1815 if ((tmp & SR_REQ) || (p == PHASE_MSGIN && c == 0))
1816 *phase = tmp & PHASE_MASK;
1817 else
1818 *phase = PHASE_UNKNOWN;
1819
1820 if (!c || (*phase == p))
1821 return 0;
1822 else
1823 return -1;
1824}
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835static int do_abort(struct Scsi_Host *host)
1836{
1837 unsigned char tmp, *msgptr, phase;
1838 int len;
1839
1840
1841 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853 while (!((tmp = NCR5380_read(STATUS_REG)) & SR_REQ))
1854 ;
1855
1856 NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp));
1857
1858 if ((tmp & PHASE_MASK) != PHASE_MSGOUT) {
1859 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN |
1860 ICR_ASSERT_ACK);
1861 while (NCR5380_read(STATUS_REG) & SR_REQ)
1862 ;
1863 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
1864 }
1865
1866 tmp = ABORT;
1867 msgptr = &tmp;
1868 len = 1;
1869 phase = PHASE_MSGOUT;
1870 NCR5380_transfer_pio(host, &phase, &len, &msgptr);
1871
1872
1873
1874
1875
1876
1877 return len ? -1 : 0;
1878}
1879
1880#if defined(REAL_DMA)
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901static int NCR5380_transfer_dma(struct Scsi_Host *instance,
1902 unsigned char *phase, int *count,
1903 unsigned char **data)
1904{
1905 SETUP_HOSTDATA(instance);
1906 register int c = *count;
1907 register unsigned char p = *phase;
1908 register unsigned char *d = *data;
1909 unsigned char tmp;
1910 unsigned long flags;
1911
1912 if ((tmp = (NCR5380_read(STATUS_REG) & PHASE_MASK)) != p) {
1913 *phase = tmp;
1914 return -1;
1915 }
1916
1917 if (atari_read_overruns && (p & SR_IO))
1918 c -= atari_read_overruns;
1919
1920 DMA_PRINTK("scsi%d: initializing DMA for %s, %d bytes %s %p\n",
1921 HOSTNO, (p & SR_IO) ? "reading" : "writing",
1922 c, (p & SR_IO) ? "to" : "from", d);
1923
1924 NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p));
1925
1926#ifdef REAL_DMA
1927 NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_ENABLE_EOP_INTR | MR_MONITOR_BSY);
1928#endif
1929
1930 if (IS_A_TT()) {
1931
1932
1933
1934 local_irq_save(flags);
1935 hostdata->dma_len = (p & SR_IO) ?
1936 NCR5380_dma_read_setup(instance, d, c) :
1937 NCR5380_dma_write_setup(instance, d, c);
1938 local_irq_restore(flags);
1939 }
1940
1941 if (p & SR_IO)
1942 NCR5380_write(START_DMA_INITIATOR_RECEIVE_REG, 0);
1943 else {
1944 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA);
1945 NCR5380_write(START_DMA_SEND_REG, 0);
1946 }
1947
1948 if (!IS_A_TT()) {
1949
1950
1951
1952 local_irq_save(flags);
1953 hostdata->dma_len = (p & SR_IO) ?
1954 NCR5380_dma_read_setup(instance, d, c) :
1955 NCR5380_dma_write_setup(instance, d, c);
1956 local_irq_restore(flags);
1957 }
1958 return 0;
1959}
1960#endif
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979static void NCR5380_information_transfer(struct Scsi_Host *instance)
1980{
1981 SETUP_HOSTDATA(instance);
1982 unsigned long flags;
1983 unsigned char msgout = NOP;
1984 int sink = 0;
1985 int len;
1986#if defined(REAL_DMA)
1987 int transfersize;
1988#endif
1989 unsigned char *data;
1990 unsigned char phase, tmp, extended_msg[10], old_phase = 0xff;
1991 Scsi_Cmnd *cmd = (Scsi_Cmnd *) hostdata->connected;
1992
1993 while (1) {
1994 tmp = NCR5380_read(STATUS_REG);
1995
1996 if (tmp & SR_REQ) {
1997 phase = (tmp & PHASE_MASK);
1998 if (phase != old_phase) {
1999 old_phase = phase;
2000 NCR_PRINT_PHASE(NDEBUG_INFORMATION);
2001 }
2002
2003 if (sink && (phase != PHASE_MSGOUT)) {
2004 NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp));
2005
2006 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN |
2007 ICR_ASSERT_ACK);
2008 while (NCR5380_read(STATUS_REG) & SR_REQ)
2009 ;
2010 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
2011 ICR_ASSERT_ATN);
2012 sink = 0;
2013 continue;
2014 }
2015
2016 switch (phase) {
2017 case PHASE_DATAOUT:
2018#if (NDEBUG & NDEBUG_NO_DATAOUT)
2019 printk("scsi%d: NDEBUG_NO_DATAOUT set, attempted DATAOUT "
2020 "aborted\n", HOSTNO);
2021 sink = 1;
2022 do_abort(instance);
2023 cmd->result = DID_ERROR << 16;
2024 cmd->scsi_done(cmd);
2025 return;
2026#endif
2027 case PHASE_DATAIN:
2028
2029
2030
2031
2032
2033 if (!cmd->SCp.this_residual && cmd->SCp.buffers_residual) {
2034 ++cmd->SCp.buffer;
2035 --cmd->SCp.buffers_residual;
2036 cmd->SCp.this_residual = cmd->SCp.buffer->length;
2037 cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
2038
2039
2040
2041 merge_contiguous_buffers(cmd);
2042 INF_PRINTK("scsi%d: %d bytes and %d buffers left\n",
2043 HOSTNO, cmd->SCp.this_residual,
2044 cmd->SCp.buffers_residual);
2045 }
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062#if defined(REAL_DMA)
2063 if (!cmd->device->borken &&
2064 (transfersize = NCR5380_dma_xfer_len(instance,cmd,phase)) > 31) {
2065 len = transfersize;
2066 cmd->SCp.phase = phase;
2067 if (NCR5380_transfer_dma(instance, &phase,
2068 &len, (unsigned char **)&cmd->SCp.ptr)) {
2069
2070
2071
2072
2073 printk(KERN_NOTICE "scsi%d: switching target %d "
2074 "lun %d to slow handshake\n", HOSTNO,
2075 cmd->device->id, cmd->device->lun);
2076 cmd->device->borken = 1;
2077 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
2078 ICR_ASSERT_ATN);
2079 sink = 1;
2080 do_abort(instance);
2081 cmd->result = DID_ERROR << 16;
2082 cmd->scsi_done(cmd);
2083
2084 } else {
2085#ifdef REAL_DMA
2086
2087
2088
2089
2090
2091 return;
2092#else
2093 cmd->SCp.this_residual -= transfersize - len;
2094#endif
2095 }
2096 } else
2097#endif
2098 NCR5380_transfer_pio(instance, &phase,
2099 (int *)&cmd->SCp.this_residual,
2100 (unsigned char **)&cmd->SCp.ptr);
2101 break;
2102 case PHASE_MSGIN:
2103 len = 1;
2104 data = &tmp;
2105 NCR5380_write(SELECT_ENABLE_REG, 0);
2106 NCR5380_transfer_pio(instance, &phase, &len, &data);
2107 cmd->SCp.Message = tmp;
2108
2109 switch (tmp) {
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120#ifdef LINKED
2121 case LINKED_CMD_COMPLETE:
2122 case LINKED_FLG_CMD_COMPLETE:
2123
2124 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
2125
2126 LNK_PRINTK("scsi%d: target %d lun %d linked command "
2127 "complete.\n", HOSTNO, cmd->device->id, cmd->device->lun);
2128
2129
2130 NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
2131
2132
2133
2134
2135
2136
2137 if (!cmd->next_link) {
2138 printk(KERN_NOTICE "scsi%d: target %d lun %d "
2139 "linked command complete, no next_link\n",
2140 HOSTNO, cmd->device->id, cmd->device->lun);
2141 sink = 1;
2142 do_abort(instance);
2143 return;
2144 }
2145
2146 initialize_SCp(cmd->next_link);
2147
2148
2149 cmd->next_link->tag = cmd->tag;
2150 cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8);
2151 LNK_PRINTK("scsi%d: target %d lun %d linked request "
2152 "done, calling scsi_done().\n",
2153 HOSTNO, cmd->device->id, cmd->device->lun);
2154#ifdef NCR5380_STATS
2155 collect_stats(hostdata, cmd);
2156#endif
2157 cmd->scsi_done(cmd);
2158 cmd = hostdata->connected;
2159 break;
2160#endif
2161 case ABORT:
2162 case COMMAND_COMPLETE:
2163
2164 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
2165
2166 falcon_dont_release++;
2167 hostdata->connected = NULL;
2168 QU_PRINTK("scsi%d: command for target %d, lun %d "
2169 "completed\n", HOSTNO, cmd->device->id, cmd->device->lun);
2170#ifdef SUPPORT_TAGS
2171 cmd_free_tag(cmd);
2172 if (status_byte(cmd->SCp.Status) == QUEUE_FULL) {
2173
2174
2175
2176
2177
2178
2179
2180
2181 TAG_ALLOC *ta = &TagAlloc[cmd->device->id][cmd->device->lun];
2182 TAG_PRINTK("scsi%d: target %d lun %d returned "
2183 "QUEUE_FULL after %d commands\n",
2184 HOSTNO, cmd->device->id, cmd->device->lun,
2185 ta->nr_allocated);
2186 if (ta->queue_size > ta->nr_allocated)
2187 ta->nr_allocated = ta->queue_size;
2188 }
2189#else
2190 hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
2191#endif
2192
2193 NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211 if (cmd->cmnd[0] != REQUEST_SENSE)
2212 cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8);
2213 else if (status_byte(cmd->SCp.Status) != GOOD)
2214 cmd->result = (cmd->result & 0x00ffff) | (DID_ERROR << 16);
2215
2216#ifdef AUTOSENSE
2217 if ((cmd->cmnd[0] == REQUEST_SENSE) &&
2218 hostdata->ses.cmd_len) {
2219 scsi_eh_restore_cmnd(cmd, &hostdata->ses);
2220 hostdata->ses.cmd_len = 0 ;
2221 }
2222
2223 if ((cmd->cmnd[0] != REQUEST_SENSE) &&
2224 (status_byte(cmd->SCp.Status) == CHECK_CONDITION)) {
2225 scsi_eh_prep_cmnd(cmd, &hostdata->ses, NULL, 0, ~0);
2226
2227 ASEN_PRINTK("scsi%d: performing request sense\n", HOSTNO);
2228
2229 local_irq_save(flags);
2230 LIST(cmd,hostdata->issue_queue);
2231 SET_NEXT(cmd, hostdata->issue_queue);
2232 hostdata->issue_queue = (Scsi_Cmnd *) cmd;
2233 local_irq_restore(flags);
2234 QU_PRINTK("scsi%d: REQUEST SENSE added to head of "
2235 "issue queue\n", H_NO(cmd));
2236 } else
2237#endif
2238 {
2239#ifdef NCR5380_STATS
2240 collect_stats(hostdata, cmd);
2241#endif
2242 cmd->scsi_done(cmd);
2243 }
2244
2245 NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
2246
2247
2248
2249
2250 NCR5380_write(TARGET_COMMAND_REG, 0);
2251
2252 while ((NCR5380_read(STATUS_REG) & SR_BSY) && !hostdata->connected)
2253 barrier();
2254
2255 falcon_dont_release--;
2256
2257
2258
2259
2260 falcon_release_lock_if_possible(hostdata);
2261 return;
2262 case MESSAGE_REJECT:
2263
2264 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
2265
2266 NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
2267 switch (hostdata->last_message) {
2268 case HEAD_OF_QUEUE_TAG:
2269 case ORDERED_QUEUE_TAG:
2270 case SIMPLE_QUEUE_TAG:
2271
2272
2273
2274
2275
2276
2277 cmd->device->tagged_supported = 0;
2278 hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);
2279 cmd->tag = TAG_NONE;
2280 TAG_PRINTK("scsi%d: target %d lun %d rejected "
2281 "QUEUE_TAG message; tagged queuing "
2282 "disabled\n",
2283 HOSTNO, cmd->device->id, cmd->device->lun);
2284 break;
2285 }
2286 break;
2287 case DISCONNECT:
2288
2289 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
2290 local_irq_save(flags);
2291 cmd->device->disconnect = 1;
2292 LIST(cmd,hostdata->disconnected_queue);
2293 SET_NEXT(cmd, hostdata->disconnected_queue);
2294 hostdata->connected = NULL;
2295 hostdata->disconnected_queue = cmd;
2296 local_irq_restore(flags);
2297 QU_PRINTK("scsi%d: command for target %d lun %d was "
2298 "moved from connected to the "
2299 "disconnected_queue\n", HOSTNO,
2300 cmd->device->id, cmd->device->lun);
2301
2302
2303
2304
2305 NCR5380_write(TARGET_COMMAND_REG, 0);
2306
2307
2308 NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
2309
2310 while ((NCR5380_read(STATUS_REG) & SR_BSY) && !hostdata->connected)
2311 barrier();
2312 return;
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323 case SAVE_POINTERS:
2324 case RESTORE_POINTERS:
2325
2326 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
2327
2328 NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
2329 break;
2330 case EXTENDED_MESSAGE:
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343 extended_msg[0] = EXTENDED_MESSAGE;
2344
2345 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
2346
2347 EXT_PRINTK("scsi%d: receiving extended message\n", HOSTNO);
2348
2349 len = 2;
2350 data = extended_msg + 1;
2351 phase = PHASE_MSGIN;
2352 NCR5380_transfer_pio(instance, &phase, &len, &data);
2353 EXT_PRINTK("scsi%d: length=%d, code=0x%02x\n", HOSTNO,
2354 (int)extended_msg[1], (int)extended_msg[2]);
2355
2356 if (!len && extended_msg[1] <=
2357 (sizeof(extended_msg) - 1)) {
2358
2359 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
2360 len = extended_msg[1] - 1;
2361 data = extended_msg + 3;
2362 phase = PHASE_MSGIN;
2363
2364 NCR5380_transfer_pio(instance, &phase, &len, &data);
2365 EXT_PRINTK("scsi%d: message received, residual %d\n",
2366 HOSTNO, len);
2367
2368 switch (extended_msg[2]) {
2369 case EXTENDED_SDTR:
2370 case EXTENDED_WDTR:
2371 case EXTENDED_MODIFY_DATA_POINTER:
2372 case EXTENDED_EXTENDED_IDENTIFY:
2373 tmp = 0;
2374 }
2375 } else if (len) {
2376 printk(KERN_NOTICE "scsi%d: error receiving "
2377 "extended message\n", HOSTNO);
2378 tmp = 0;
2379 } else {
2380 printk(KERN_NOTICE "scsi%d: extended message "
2381 "code %02x length %d is too long\n",
2382 HOSTNO, extended_msg[2], extended_msg[1]);
2383 tmp = 0;
2384 }
2385
2386
2387
2388
2389
2390
2391 default:
2392 if (!tmp) {
2393 printk(KERN_DEBUG "scsi%d: rejecting message ", HOSTNO);
2394 spi_print_msg(extended_msg);
2395 printk("\n");
2396 } else if (tmp != EXTENDED_MESSAGE)
2397 printk(KERN_DEBUG "scsi%d: rejecting unknown "
2398 "message %02x from target %d, lun %d\n",
2399 HOSTNO, tmp, cmd->device->id, cmd->device->lun);
2400 else
2401 printk(KERN_DEBUG "scsi%d: rejecting unknown "
2402 "extended message "
2403 "code %02x, length %d from target %d, lun %d\n",
2404 HOSTNO, extended_msg[1], extended_msg[0],
2405 cmd->device->id, cmd->device->lun);
2406
2407
2408 msgout = MESSAGE_REJECT;
2409 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
2410 break;
2411 }
2412 break;
2413 case PHASE_MSGOUT:
2414 len = 1;
2415 data = &msgout;
2416 hostdata->last_message = msgout;
2417 NCR5380_transfer_pio(instance, &phase, &len, &data);
2418 if (msgout == ABORT) {
2419#ifdef SUPPORT_TAGS
2420 cmd_free_tag(cmd);
2421#else
2422 hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
2423#endif
2424 hostdata->connected = NULL;
2425 cmd->result = DID_ERROR << 16;
2426#ifdef NCR5380_STATS
2427 collect_stats(hostdata, cmd);
2428#endif
2429 cmd->scsi_done(cmd);
2430 NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
2431 falcon_release_lock_if_possible(hostdata);
2432 return;
2433 }
2434 msgout = NOP;
2435 break;
2436 case PHASE_CMDOUT:
2437 len = cmd->cmd_len;
2438 data = cmd->cmnd;
2439
2440
2441
2442
2443
2444 NCR5380_transfer_pio(instance, &phase, &len, &data);
2445 break;
2446 case PHASE_STATIN:
2447 len = 1;
2448 data = &tmp;
2449 NCR5380_transfer_pio(instance, &phase, &len, &data);
2450 cmd->SCp.Status = tmp;
2451 break;
2452 default:
2453 printk("scsi%d: unknown phase\n", HOSTNO);
2454 NCR_PRINT(NDEBUG_ANY);
2455 }
2456 }
2457 }
2458}
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472static void NCR5380_reselect(struct Scsi_Host *instance)
2473{
2474 SETUP_HOSTDATA(instance);
2475 unsigned char target_mask;
2476 unsigned char lun, phase;
2477 int len;
2478#ifdef SUPPORT_TAGS
2479 unsigned char tag;
2480#endif
2481 unsigned char msg[3];
2482 unsigned char *data;
2483 Scsi_Cmnd *tmp = NULL, *prev;
2484
2485
2486
2487
2488
2489
2490
2491 NCR5380_write(MODE_REG, MR_BASE);
2492 hostdata->restart_select = 1;
2493
2494 target_mask = NCR5380_read(CURRENT_SCSI_DATA_REG) & ~(hostdata->id_mask);
2495
2496 RSL_PRINTK("scsi%d: reselect\n", HOSTNO);
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_BSY);
2508
2509 while (NCR5380_read(STATUS_REG) & SR_SEL)
2510 ;
2511 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
2512
2513
2514
2515
2516
2517 while (!(NCR5380_read(STATUS_REG) & SR_REQ))
2518 ;
2519
2520 len = 1;
2521 data = msg;
2522 phase = PHASE_MSGIN;
2523 NCR5380_transfer_pio(instance, &phase, &len, &data);
2524
2525 if (!(msg[0] & 0x80)) {
2526 printk(KERN_DEBUG "scsi%d: expecting IDENTIFY message, got ", HOSTNO);
2527 spi_print_msg(msg);
2528 do_abort(instance);
2529 return;
2530 }
2531 lun = (msg[0] & 0x07);
2532
2533#ifdef SUPPORT_TAGS
2534
2535
2536
2537
2538 tag = TAG_NONE;
2539 if (phase == PHASE_MSGIN && setup_use_tagged_queuing) {
2540
2541 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
2542 len = 2;
2543 data = msg + 1;
2544 if (!NCR5380_transfer_pio(instance, &phase, &len, &data) &&
2545 msg[1] == SIMPLE_QUEUE_TAG)
2546 tag = msg[2];
2547 TAG_PRINTK("scsi%d: target mask %02x, lun %d sent tag %d at "
2548 "reselection\n", HOSTNO, target_mask, lun, tag);
2549 }
2550#endif
2551
2552
2553
2554
2555
2556
2557 for (tmp = (Scsi_Cmnd *) hostdata->disconnected_queue, prev = NULL;
2558 tmp; prev = tmp, tmp = NEXT(tmp)) {
2559 if ((target_mask == (1 << tmp->device->id)) && (lun == tmp->device->lun)
2560#ifdef SUPPORT_TAGS
2561 && (tag == tmp->tag)
2562#endif
2563 ) {
2564
2565 falcon_dont_release++;
2566 if (prev) {
2567 REMOVE(prev, NEXT(prev), tmp, NEXT(tmp));
2568 SET_NEXT(prev, NEXT(tmp));
2569 } else {
2570 REMOVE(-1, hostdata->disconnected_queue, tmp, NEXT(tmp));
2571 hostdata->disconnected_queue = NEXT(tmp);
2572 }
2573 SET_NEXT(tmp, NULL);
2574 break;
2575 }
2576 }
2577
2578 if (!tmp) {
2579 printk(KERN_WARNING "scsi%d: warning: target bitmask %02x lun %d "
2580#ifdef SUPPORT_TAGS
2581 "tag %d "
2582#endif
2583 "not in disconnected_queue.\n",
2584 HOSTNO, target_mask, lun
2585#ifdef SUPPORT_TAGS
2586 , tag
2587#endif
2588 );
2589
2590
2591
2592
2593 do_abort(instance);
2594 return;
2595 }
2596
2597
2598 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
2599
2600 hostdata->connected = tmp;
2601 RSL_PRINTK("scsi%d: nexus established, target = %d, lun = %d, tag = %d\n",
2602 HOSTNO, tmp->device->id, tmp->device->lun, tmp->tag);
2603 falcon_dont_release--;
2604}
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624static
2625int NCR5380_abort(Scsi_Cmnd *cmd)
2626{
2627 struct Scsi_Host *instance = cmd->device->host;
2628 SETUP_HOSTDATA(instance);
2629 Scsi_Cmnd *tmp, **prev;
2630 unsigned long flags;
2631
2632 printk(KERN_NOTICE "scsi%d: aborting command\n", HOSTNO);
2633 scsi_print_command(cmd);
2634
2635 NCR5380_print_status(instance);
2636
2637 local_irq_save(flags);
2638
2639 if (!IS_A_TT() && !falcon_got_lock)
2640 printk(KERN_ERR "scsi%d: !!BINGO!! Falcon has no lock in NCR5380_abort\n",
2641 HOSTNO);
2642
2643 ABRT_PRINTK("scsi%d: abort called basr 0x%02x, sr 0x%02x\n", HOSTNO,
2644 NCR5380_read(BUS_AND_STATUS_REG),
2645 NCR5380_read(STATUS_REG));
2646
2647#if 1
2648
2649
2650
2651
2652
2653
2654 if (hostdata->connected == cmd) {
2655
2656 ABRT_PRINTK("scsi%d: aborting connected command\n", HOSTNO);
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674 if (do_abort(instance) == 0) {
2675 hostdata->aborted = 1;
2676 hostdata->connected = NULL;
2677 cmd->result = DID_ABORT << 16;
2678#ifdef SUPPORT_TAGS
2679 cmd_free_tag(cmd);
2680#else
2681 hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
2682#endif
2683 local_irq_restore(flags);
2684 cmd->scsi_done(cmd);
2685 falcon_release_lock_if_possible(hostdata);
2686 return SCSI_ABORT_SUCCESS;
2687 } else {
2688
2689 printk("scsi%d: abort of connected command failed!\n", HOSTNO);
2690 return SCSI_ABORT_ERROR;
2691 }
2692 }
2693#endif
2694
2695
2696
2697
2698
2699 for (prev = (Scsi_Cmnd **)&(hostdata->issue_queue),
2700 tmp = (Scsi_Cmnd *)hostdata->issue_queue;
2701 tmp; prev = NEXTADDR(tmp), tmp = NEXT(tmp)) {
2702 if (cmd == tmp) {
2703 REMOVE(5, *prev, tmp, NEXT(tmp));
2704 (*prev) = NEXT(tmp);
2705 SET_NEXT(tmp, NULL);
2706 tmp->result = DID_ABORT << 16;
2707 local_irq_restore(flags);
2708 ABRT_PRINTK("scsi%d: abort removed command from issue queue.\n",
2709 HOSTNO);
2710
2711
2712 tmp->scsi_done(tmp);
2713 falcon_release_lock_if_possible(hostdata);
2714 return SCSI_ABORT_SUCCESS;
2715 }
2716 }
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729 if (hostdata->connected) {
2730 local_irq_restore(flags);
2731 ABRT_PRINTK("scsi%d: abort failed, command connected.\n", HOSTNO);
2732 return SCSI_ABORT_SNOOZE;
2733 }
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760 for (tmp = (Scsi_Cmnd *) hostdata->disconnected_queue; tmp;
2761 tmp = NEXT(tmp)) {
2762 if (cmd == tmp) {
2763 local_irq_restore(flags);
2764 ABRT_PRINTK("scsi%d: aborting disconnected command.\n", HOSTNO);
2765
2766 if (NCR5380_select(instance, cmd, (int)cmd->tag))
2767 return SCSI_ABORT_BUSY;
2768
2769 ABRT_PRINTK("scsi%d: nexus reestablished.\n", HOSTNO);
2770
2771 do_abort(instance);
2772
2773 local_irq_save(flags);
2774 for (prev = (Scsi_Cmnd **)&(hostdata->disconnected_queue),
2775 tmp = (Scsi_Cmnd *)hostdata->disconnected_queue;
2776 tmp; prev = NEXTADDR(tmp), tmp = NEXT(tmp)) {
2777 if (cmd == tmp) {
2778 REMOVE(5, *prev, tmp, NEXT(tmp));
2779 *prev = NEXT(tmp);
2780 SET_NEXT(tmp, NULL);
2781 tmp->result = DID_ABORT << 16;
2782
2783
2784
2785
2786#ifdef SUPPORT_TAGS
2787 cmd_free_tag(tmp);
2788#else
2789 hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
2790#endif
2791 local_irq_restore(flags);
2792 tmp->scsi_done(tmp);
2793 falcon_release_lock_if_possible(hostdata);
2794 return SCSI_ABORT_SUCCESS;
2795 }
2796 }
2797 }
2798 }
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810 local_irq_restore(flags);
2811 printk(KERN_INFO "scsi%d: warning : SCSI command probably completed successfully before abortion\n", HOSTNO);
2812
2813
2814
2815
2816
2817 falcon_release_lock_if_possible(hostdata);
2818
2819 return SCSI_ABORT_NOT_RUNNING;
2820}
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832static int NCR5380_bus_reset(Scsi_Cmnd *cmd)
2833{
2834 SETUP_HOSTDATA(cmd->device->host);
2835 int i;
2836 unsigned long flags;
2837#if 1
2838 Scsi_Cmnd *connected, *disconnected_queue;
2839#endif
2840
2841 if (!IS_A_TT() && !falcon_got_lock)
2842 printk(KERN_ERR "scsi%d: !!BINGO!! Falcon has no lock in NCR5380_reset\n",
2843 H_NO(cmd));
2844
2845 NCR5380_print_status(cmd->device->host);
2846
2847
2848 NCR5380_write(TARGET_COMMAND_REG,
2849 PHASE_SR_TO_TCR(NCR5380_read(STATUS_REG)));
2850
2851 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST);
2852 udelay(40);
2853
2854 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
2855 NCR5380_write(MODE_REG, MR_BASE);
2856 NCR5380_write(TARGET_COMMAND_REG, 0);
2857 NCR5380_write(SELECT_ENABLE_REG, 0);
2858
2859
2860 (void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
2861
2862#if 1
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872 local_irq_save(flags);
2873 connected = (Scsi_Cmnd *)hostdata->connected;
2874 hostdata->connected = NULL;
2875 disconnected_queue = (Scsi_Cmnd *)hostdata->disconnected_queue;
2876 hostdata->disconnected_queue = NULL;
2877#ifdef SUPPORT_TAGS
2878 free_all_tags();
2879#endif
2880 for (i = 0; i < 8; ++i)
2881 hostdata->busy[i] = 0;
2882#ifdef REAL_DMA
2883 hostdata->dma_len = 0;
2884#endif
2885 local_irq_restore(flags);
2886
2887
2888
2889
2890
2891
2892 if ((cmd = connected)) {
2893 ABRT_PRINTK("scsi%d: reset aborted a connected command\n", H_NO(cmd));
2894 cmd->result = (cmd->result & 0xffff) | (DID_RESET << 16);
2895 cmd->scsi_done(cmd);
2896 }
2897
2898 for (i = 0; (cmd = disconnected_queue); ++i) {
2899 disconnected_queue = NEXT(cmd);
2900 SET_NEXT(cmd, NULL);
2901 cmd->result = (cmd->result & 0xffff) | (DID_RESET << 16);
2902 cmd->scsi_done(cmd);
2903 }
2904 if (i > 0)
2905 ABRT_PRINTK("scsi: reset aborted %d disconnected command(s)\n", i);
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918 return SCSI_RESET_SUCCESS | SCSI_RESET_BUS_RESET;
2919#else
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944 if (hostdata->issue_queue)
2945 ABRT_PRINTK("scsi%d: reset aborted issued command(s)\n", H_NO(cmd));
2946 if (hostdata->connected)
2947 ABRT_PRINTK("scsi%d: reset aborted a connected command\n", H_NO(cmd));
2948 if (hostdata->disconnected_queue)
2949 ABRT_PRINTK("scsi%d: reset aborted disconnected command(s)\n", H_NO(cmd));
2950
2951 local_irq_save(flags);
2952 hostdata->issue_queue = NULL;
2953 hostdata->connected = NULL;
2954 hostdata->disconnected_queue = NULL;
2955#ifdef SUPPORT_TAGS
2956 free_all_tags();
2957#endif
2958 for (i = 0; i < 8; ++i)
2959 hostdata->busy[i] = 0;
2960#ifdef REAL_DMA
2961 hostdata->dma_len = 0;
2962#endif
2963 local_irq_restore(flags);
2964
2965
2966 return SCSI_RESET_WAKEUP | SCSI_RESET_BUS_RESET;
2967#endif
2968}
2969