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 NCR5380_print_status(struct Scsi_Host *instance)
723{
724 char *pr_bfr;
725 char *start;
726 int len;
727
728 NCR_PRINT(NDEBUG_ANY);
729 NCR_PRINT_PHASE(NDEBUG_ANY);
730
731 pr_bfr = (char *)__get_free_page(GFP_ATOMIC);
732 if (!pr_bfr) {
733 printk("NCR5380_print_status: no memory for print buffer\n");
734 return;
735 }
736 len = NCR5380_proc_info(instance, pr_bfr, &start, 0, PAGE_SIZE, 0);
737 pr_bfr[len] = 0;
738 printk("\n%s\n", pr_bfr);
739 free_page((unsigned long)pr_bfr);
740}
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757#undef SPRINTF
758#define SPRINTF(fmt,args...) \
759 do { \
760 if (pos + strlen(fmt) + 20 < buffer + length) \
761 pos += sprintf(pos, fmt , ## args); \
762 } while(0)
763static char *lprint_Scsi_Cmnd(Scsi_Cmnd *cmd, char *pos, char *buffer, int length);
764
765static int NCR5380_proc_info(struct Scsi_Host *instance, char *buffer,
766 char **start, off_t offset, int length, int inout)
767{
768 char *pos = buffer;
769 struct NCR5380_hostdata *hostdata;
770 Scsi_Cmnd *ptr;
771 unsigned long flags;
772 off_t begin = 0;
773#define check_offset() \
774 do { \
775 if (pos - buffer < offset - begin) { \
776 begin += pos - buffer; \
777 pos = buffer; \
778 } \
779 } while (0)
780
781 hostdata = (struct NCR5380_hostdata *)instance->hostdata;
782
783 if (inout)
784 return -ENOSYS;
785 SPRINTF("NCR5380 core release=%d.\n", NCR5380_PUBLIC_RELEASE);
786 check_offset();
787 local_irq_save(flags);
788 SPRINTF("NCR5380: coroutine is%s running.\n",
789 main_running ? "" : "n't");
790 check_offset();
791 if (!hostdata->connected)
792 SPRINTF("scsi%d: no currently connected command\n", HOSTNO);
793 else
794 pos = lprint_Scsi_Cmnd((Scsi_Cmnd *) hostdata->connected,
795 pos, buffer, length);
796 SPRINTF("scsi%d: issue_queue\n", HOSTNO);
797 check_offset();
798 for (ptr = (Scsi_Cmnd *)hostdata->issue_queue; ptr; ptr = NEXT(ptr)) {
799 pos = lprint_Scsi_Cmnd(ptr, pos, buffer, length);
800 check_offset();
801 }
802
803 SPRINTF("scsi%d: disconnected_queue\n", HOSTNO);
804 check_offset();
805 for (ptr = (Scsi_Cmnd *) hostdata->disconnected_queue; ptr;
806 ptr = NEXT(ptr)) {
807 pos = lprint_Scsi_Cmnd(ptr, pos, buffer, length);
808 check_offset();
809 }
810
811 local_irq_restore(flags);
812 *start = buffer + (offset - begin);
813 if (pos - buffer < offset - begin)
814 return 0;
815 else if (pos - buffer - (offset - begin) < length)
816 return pos - buffer - (offset - begin);
817 return length;
818}
819
820static char *lprint_Scsi_Cmnd(Scsi_Cmnd *cmd, char *pos, char *buffer, int length)
821{
822 int i, s;
823 unsigned char *command;
824 SPRINTF("scsi%d: destination target %d, lun %d\n",
825 H_NO(cmd), cmd->device->id, cmd->device->lun);
826 SPRINTF(" command = ");
827 command = cmd->cmnd;
828 SPRINTF("%2d (0x%02x)", command[0], command[0]);
829 for (i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i)
830 SPRINTF(" %02x", command[i]);
831 SPRINTF("\n");
832 return pos;
833}
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848static int __init NCR5380_init(struct Scsi_Host *instance, int flags)
849{
850 int i;
851 SETUP_HOSTDATA(instance);
852
853 NCR5380_all_init();
854
855 hostdata->aborted = 0;
856 hostdata->id_mask = 1 << instance->this_id;
857 hostdata->id_higher_mask = 0;
858 for (i = hostdata->id_mask; i <= 0x80; i <<= 1)
859 if (i > hostdata->id_mask)
860 hostdata->id_higher_mask |= i;
861 for (i = 0; i < 8; ++i)
862 hostdata->busy[i] = 0;
863#ifdef SUPPORT_TAGS
864 init_tags();
865#endif
866#if defined (REAL_DMA)
867 hostdata->dma_len = 0;
868#endif
869 hostdata->targets_present = 0;
870 hostdata->connected = NULL;
871 hostdata->issue_queue = NULL;
872 hostdata->disconnected_queue = NULL;
873 hostdata->flags = FLAG_CHECK_LAST_BYTE_SENT;
874
875 if (!the_template) {
876 the_template = instance->hostt;
877 first_instance = instance;
878 }
879
880#ifndef AUTOSENSE
881 if ((instance->cmd_per_lun > 1) || (instance->can_queue > 1))
882 printk("scsi%d: WARNING : support for multiple outstanding commands enabled\n"
883 " without AUTOSENSE option, contingent allegiance conditions may\n"
884 " be incorrectly cleared.\n", HOSTNO);
885#endif
886
887 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
888 NCR5380_write(MODE_REG, MR_BASE);
889 NCR5380_write(TARGET_COMMAND_REG, 0);
890 NCR5380_write(SELECT_ENABLE_REG, 0);
891
892 return 0;
893}
894
895static void NCR5380_exit(struct Scsi_Host *instance)
896{
897
898}
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918static int NCR5380_queue_command_lck(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
919{
920 SETUP_HOSTDATA(cmd->device->host);
921 Scsi_Cmnd *tmp;
922 unsigned long flags;
923
924#if (NDEBUG & NDEBUG_NO_WRITE)
925 switch (cmd->cmnd[0]) {
926 case WRITE_6:
927 case WRITE_10:
928 printk(KERN_NOTICE "scsi%d: WRITE attempted with NO_WRITE debugging flag set\n",
929 H_NO(cmd));
930 cmd->result = (DID_ERROR << 16);
931 done(cmd);
932 return 0;
933 }
934#endif
935
936#ifdef NCR5380_STATS
937# if 0
938 if (!hostdata->connected && !hostdata->issue_queue &&
939 !hostdata->disconnected_queue) {
940 hostdata->timebase = jiffies;
941 }
942# endif
943# ifdef NCR5380_STAT_LIMIT
944 if (scsi_bufflen(cmd) > NCR5380_STAT_LIMIT)
945# endif
946 switch (cmd->cmnd[0]) {
947 case WRITE:
948 case WRITE_6:
949 case WRITE_10:
950 hostdata->time_write[cmd->device->id] -= (jiffies - hostdata->timebase);
951 hostdata->bytes_write[cmd->device->id] += scsi_bufflen(cmd);
952 hostdata->pendingw++;
953 break;
954 case READ:
955 case READ_6:
956 case READ_10:
957 hostdata->time_read[cmd->device->id] -= (jiffies - hostdata->timebase);
958 hostdata->bytes_read[cmd->device->id] += scsi_bufflen(cmd);
959 hostdata->pendingr++;
960 break;
961 }
962#endif
963
964
965
966
967
968
969 SET_NEXT(cmd, NULL);
970 cmd->scsi_done = done;
971
972 cmd->result = 0;
973
974
975
976
977
978
979
980
981 local_irq_save(flags);
982
983
984
985
986
987
988
989
990
991
992
993
994 if (!IS_A_TT()) {
995
996 falcon_get_lock();
997
998 }
999 if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) {
1000 LIST(cmd, hostdata->issue_queue);
1001 SET_NEXT(cmd, hostdata->issue_queue);
1002 hostdata->issue_queue = cmd;
1003 } else {
1004 for (tmp = (Scsi_Cmnd *)hostdata->issue_queue;
1005 NEXT(tmp); tmp = NEXT(tmp))
1006 ;
1007 LIST(cmd, tmp);
1008 SET_NEXT(tmp, cmd);
1009 }
1010 local_irq_restore(flags);
1011
1012 QU_PRINTK("scsi%d: command added to %s of queue\n", H_NO(cmd),
1013 (cmd->cmnd[0] == REQUEST_SENSE) ? "head" : "tail");
1014
1015
1016
1017
1018
1019
1020
1021
1022 if (in_interrupt() || ((flags >> 8) & 7) >= 6)
1023 queue_main();
1024 else
1025 NCR5380_main(NULL);
1026 return 0;
1027}
1028
1029static DEF_SCSI_QCMD(NCR5380_queue_command)
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043static void NCR5380_main(struct work_struct *work)
1044{
1045 Scsi_Cmnd *tmp, *prev;
1046 struct Scsi_Host *instance = first_instance;
1047 struct NCR5380_hostdata *hostdata = HOSTDATA(instance);
1048 int done;
1049 unsigned long flags;
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072 if (main_running)
1073 return;
1074 main_running = 1;
1075
1076 local_save_flags(flags);
1077 do {
1078 local_irq_disable();
1079 done = 1;
1080
1081 if (!hostdata->connected) {
1082 MAIN_PRINTK("scsi%d: not connected\n", HOSTNO);
1083
1084
1085
1086
1087#if (NDEBUG & NDEBUG_LISTS)
1088 for (tmp = (Scsi_Cmnd *) hostdata->issue_queue, prev = NULL;
1089 tmp && (tmp != prev); prev = tmp, tmp = NEXT(tmp))
1090 ;
1091
1092 if ((tmp == prev) && tmp)
1093 printk(" LOOP\n");
1094
1095#endif
1096 for (tmp = (Scsi_Cmnd *) hostdata->issue_queue,
1097 prev = NULL; tmp; prev = tmp, tmp = NEXT(tmp)) {
1098
1099#if (NDEBUG & NDEBUG_LISTS)
1100 if (prev != tmp)
1101 printk("MAIN tmp=%p target=%d busy=%d lun=%d\n",
1102 tmp, tmp->device->id, hostdata->busy[tmp->device->id],
1103 tmp->device->lun);
1104#endif
1105
1106
1107 if (
1108#ifdef SUPPORT_TAGS
1109 !is_lun_busy( tmp, tmp->cmnd[0] != REQUEST_SENSE)
1110#else
1111 !(hostdata->busy[tmp->device->id] & (1 << tmp->device->lun))
1112#endif
1113 ) {
1114
1115 local_irq_disable();
1116 if (prev) {
1117 REMOVE(prev, NEXT(prev), tmp, NEXT(tmp));
1118 SET_NEXT(prev, NEXT(tmp));
1119 } else {
1120 REMOVE(-1, hostdata->issue_queue, tmp, NEXT(tmp));
1121 hostdata->issue_queue = NEXT(tmp);
1122 }
1123 SET_NEXT(tmp, NULL);
1124 falcon_dont_release++;
1125
1126
1127 local_irq_restore(flags);
1128
1129
1130
1131
1132
1133
1134
1135 MAIN_PRINTK("scsi%d: main(): command for target %d "
1136 "lun %d removed from issue_queue\n",
1137 HOSTNO, tmp->device->id, tmp->device->lun);
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148#ifdef SUPPORT_TAGS
1149 cmd_get_tag(tmp, tmp->cmnd[0] != REQUEST_SENSE);
1150#endif
1151 if (!NCR5380_select(instance, tmp,
1152 (tmp->cmnd[0] == REQUEST_SENSE) ? TAG_NONE :
1153 TAG_NEXT)) {
1154 falcon_dont_release--;
1155
1156 falcon_release_lock_if_possible(hostdata);
1157 break;
1158 } else {
1159 local_irq_disable();
1160 LIST(tmp, hostdata->issue_queue);
1161 SET_NEXT(tmp, hostdata->issue_queue);
1162 hostdata->issue_queue = tmp;
1163#ifdef SUPPORT_TAGS
1164 cmd_free_tag(tmp);
1165#endif
1166 falcon_dont_release--;
1167 local_irq_restore(flags);
1168 MAIN_PRINTK("scsi%d: main(): select() failed, "
1169 "returned to issue_queue\n", HOSTNO);
1170 if (hostdata->connected)
1171 break;
1172 }
1173 }
1174 }
1175 }
1176
1177 if (hostdata->connected
1178#ifdef REAL_DMA
1179 && !hostdata->dma_len
1180#endif
1181 ) {
1182 local_irq_restore(flags);
1183 MAIN_PRINTK("scsi%d: main: performing information transfer\n",
1184 HOSTNO);
1185 NCR5380_information_transfer(instance);
1186 MAIN_PRINTK("scsi%d: main: done set false\n", HOSTNO);
1187 done = 0;
1188 }
1189 } while (!done);
1190
1191
1192
1193
1194 main_running = 0;
1195 local_irq_restore(flags);
1196}
1197
1198
1199#ifdef REAL_DMA
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210static void NCR5380_dma_complete(struct Scsi_Host *instance)
1211{
1212 SETUP_HOSTDATA(instance);
1213 int transfered, saved_data = 0, overrun = 0, cnt, toPIO;
1214 unsigned char **data, p;
1215 volatile int *count;
1216
1217 if (!hostdata->connected) {
1218 printk(KERN_WARNING "scsi%d: received end of DMA interrupt with "
1219 "no connected cmd\n", HOSTNO);
1220 return;
1221 }
1222
1223 if (atari_read_overruns) {
1224 p = hostdata->connected->SCp.phase;
1225 if (p & SR_IO) {
1226 udelay(10);
1227 if ((NCR5380_read(BUS_AND_STATUS_REG) &
1228 (BASR_PHASE_MATCH|BASR_ACK)) ==
1229 (BASR_PHASE_MATCH|BASR_ACK)) {
1230 saved_data = NCR5380_read(INPUT_DATA_REG);
1231 overrun = 1;
1232 DMA_PRINTK("scsi%d: read overrun handled\n", HOSTNO);
1233 }
1234 }
1235 }
1236
1237 DMA_PRINTK("scsi%d: real DMA transfer complete, basr 0x%X, sr 0x%X\n",
1238 HOSTNO, NCR5380_read(BUS_AND_STATUS_REG),
1239 NCR5380_read(STATUS_REG));
1240
1241 (void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
1242 NCR5380_write(MODE_REG, MR_BASE);
1243 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
1244
1245 transfered = hostdata->dma_len - NCR5380_dma_residual(instance);
1246 hostdata->dma_len = 0;
1247
1248 data = (unsigned char **)&hostdata->connected->SCp.ptr;
1249 count = &hostdata->connected->SCp.this_residual;
1250 *data += transfered;
1251 *count -= transfered;
1252
1253 if (atari_read_overruns) {
1254 if ((NCR5380_read(STATUS_REG) & PHASE_MASK) == p && (p & SR_IO)) {
1255 cnt = toPIO = atari_read_overruns;
1256 if (overrun) {
1257 DMA_PRINTK("Got an input overrun, using saved byte\n");
1258 *(*data)++ = saved_data;
1259 (*count)--;
1260 cnt--;
1261 toPIO--;
1262 }
1263 DMA_PRINTK("Doing %d-byte PIO to 0x%08lx\n", cnt, (long)*data);
1264 NCR5380_transfer_pio(instance, &p, &cnt, data);
1265 *count -= toPIO - cnt;
1266 }
1267 }
1268}
1269#endif
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283static irqreturn_t NCR5380_intr(int irq, void *dev_id)
1284{
1285 struct Scsi_Host *instance = first_instance;
1286 int done = 1, handled = 0;
1287 unsigned char basr;
1288
1289 INT_PRINTK("scsi%d: NCR5380 irq triggered\n", HOSTNO);
1290
1291
1292 basr = NCR5380_read(BUS_AND_STATUS_REG);
1293 INT_PRINTK("scsi%d: BASR=%02x\n", HOSTNO, basr);
1294
1295 if (basr & BASR_IRQ) {
1296 NCR_PRINT(NDEBUG_INTR);
1297 if ((NCR5380_read(STATUS_REG) & (SR_SEL|SR_IO)) == (SR_SEL|SR_IO)) {
1298 done = 0;
1299 ENABLE_IRQ();
1300 INT_PRINTK("scsi%d: SEL interrupt\n", HOSTNO);
1301 NCR5380_reselect(instance);
1302 (void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
1303 } else if (basr & BASR_PARITY_ERROR) {
1304 INT_PRINTK("scsi%d: PARITY interrupt\n", HOSTNO);
1305 (void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
1306 } else if ((NCR5380_read(STATUS_REG) & SR_RST) == SR_RST) {
1307 INT_PRINTK("scsi%d: RESET interrupt\n", HOSTNO);
1308 (void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
1309 } else {
1310
1311
1312
1313
1314
1315#if defined(REAL_DMA)
1316
1317
1318
1319
1320
1321
1322 if ((NCR5380_read(MODE_REG) & MR_DMA_MODE) &&
1323 ((basr & BASR_END_DMA_TRANSFER) ||
1324 !(basr & BASR_PHASE_MATCH))) {
1325
1326 INT_PRINTK("scsi%d: PHASE MISM or EOP interrupt\n", HOSTNO);
1327 NCR5380_dma_complete( instance );
1328 done = 0;
1329 ENABLE_IRQ();
1330 } else
1331#endif
1332 {
1333
1334 if (basr & BASR_PHASE_MATCH)
1335 printk(KERN_NOTICE "scsi%d: unknown interrupt, "
1336 "BASR 0x%x, MR 0x%x, SR 0x%x\n",
1337 HOSTNO, basr, NCR5380_read(MODE_REG),
1338 NCR5380_read(STATUS_REG));
1339 (void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
1340 }
1341 }
1342 handled = 1;
1343 } else {
1344 printk(KERN_NOTICE "scsi%d: interrupt without IRQ bit set in BASR, "
1345 "BASR 0x%X, MR 0x%X, SR 0x%x\n", HOSTNO, basr,
1346 NCR5380_read(MODE_REG), NCR5380_read(STATUS_REG));
1347 (void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
1348 }
1349
1350 if (!done) {
1351 INT_PRINTK("scsi%d: in int routine, calling main\n", HOSTNO);
1352
1353 queue_main();
1354 }
1355 return IRQ_RETVAL(handled);
1356}
1357
1358#ifdef NCR5380_STATS
1359static void collect_stats(struct NCR5380_hostdata* hostdata, Scsi_Cmnd *cmd)
1360{
1361# ifdef NCR5380_STAT_LIMIT
1362 if (scsi_bufflen(cmd) > NCR5380_STAT_LIMIT)
1363# endif
1364 switch (cmd->cmnd[0]) {
1365 case WRITE:
1366 case WRITE_6:
1367 case WRITE_10:
1368 hostdata->time_write[cmd->device->id] += (jiffies - hostdata->timebase);
1369
1370 hostdata->pendingw--;
1371 break;
1372 case READ:
1373 case READ_6:
1374 case READ_10:
1375 hostdata->time_read[cmd->device->id] += (jiffies - hostdata->timebase);
1376
1377 hostdata->pendingr--;
1378 break;
1379 }
1380}
1381#endif
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd *cmd, int tag)
1415{
1416 SETUP_HOSTDATA(instance);
1417 unsigned char tmp[3], phase;
1418 unsigned char *data;
1419 int len;
1420 unsigned long timeout;
1421 unsigned long flags;
1422
1423 hostdata->restart_select = 0;
1424 NCR_PRINT(NDEBUG_ARBITRATION);
1425 ARB_PRINTK("scsi%d: starting arbitration, id = %d\n", HOSTNO,
1426 instance->this_id);
1427
1428
1429
1430
1431
1432
1433 local_irq_save(flags);
1434 if (hostdata->connected) {
1435 local_irq_restore(flags);
1436 return -1;
1437 }
1438 NCR5380_write(TARGET_COMMAND_REG, 0);
1439
1440
1441
1442
1443
1444 NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask);
1445 NCR5380_write(MODE_REG, MR_ARBITRATE);
1446
1447 local_irq_restore(flags);
1448
1449
1450#if defined(NCR_TIMEOUT)
1451 {
1452 unsigned long timeout = jiffies + 2*NCR_TIMEOUT;
1453
1454 while (!(NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_PROGRESS) &&
1455 time_before(jiffies, timeout) && !hostdata->connected)
1456 ;
1457 if (time_after_eq(jiffies, timeout)) {
1458 printk("scsi : arbitration timeout at %d\n", __LINE__);
1459 NCR5380_write(MODE_REG, MR_BASE);
1460 NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
1461 return -1;
1462 }
1463 }
1464#else
1465 while (!(NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_PROGRESS) &&
1466 !hostdata->connected)
1467 ;
1468#endif
1469
1470 ARB_PRINTK("scsi%d: arbitration complete\n", HOSTNO);
1471
1472 if (hostdata->connected) {
1473 NCR5380_write(MODE_REG, MR_BASE);
1474 return -1;
1475 }
1476
1477
1478
1479
1480
1481
1482
1483 udelay(3);
1484
1485
1486 if ((NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) ||
1487 (NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_higher_mask) ||
1488 (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) ||
1489 hostdata->connected) {
1490 NCR5380_write(MODE_REG, MR_BASE);
1491 ARB_PRINTK("scsi%d: lost arbitration, deasserting MR_ARBITRATE\n",
1492 HOSTNO);
1493 return -1;
1494 }
1495
1496
1497
1498
1499 NCR5380_write(INITIATOR_COMMAND_REG,
1500 ICR_BASE | ICR_ASSERT_SEL | ICR_ASSERT_BSY);
1501
1502 if ((NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) ||
1503 hostdata->connected) {
1504 NCR5380_write(MODE_REG, MR_BASE);
1505 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
1506 ARB_PRINTK("scsi%d: lost arbitration, deasserting ICR_ASSERT_SEL\n",
1507 HOSTNO);
1508 return -1;
1509 }
1510
1511
1512
1513
1514
1515
1516#ifdef CONFIG_ATARI_SCSI_TOSHIBA_DELAY
1517
1518 udelay(15);
1519#else
1520 udelay(2);
1521#endif
1522
1523 if (hostdata->connected) {
1524 NCR5380_write(MODE_REG, MR_BASE);
1525 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
1526 return -1;
1527 }
1528
1529 ARB_PRINTK("scsi%d: won arbitration\n", HOSTNO);
1530
1531
1532
1533
1534
1535
1536 NCR5380_write(OUTPUT_DATA_REG, (hostdata->id_mask | (1 << cmd->device->id)));
1537
1538
1539
1540
1541
1542
1543
1544 NCR5380_write(INITIATOR_COMMAND_REG, (ICR_BASE | ICR_ASSERT_BSY |
1545 ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_SEL ));
1546 NCR5380_write(MODE_REG, MR_BASE);
1547
1548
1549
1550
1551
1552
1553 if (hostdata->connected) {
1554 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
1555 return -1;
1556 }
1557
1558 NCR5380_write(SELECT_ENABLE_REG, 0);
1559
1560
1561
1562
1563
1564 udelay(1);
1565
1566
1567 NCR5380_write(INITIATOR_COMMAND_REG, (ICR_BASE | ICR_ASSERT_DATA |
1568 ICR_ASSERT_ATN | ICR_ASSERT_SEL));
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587 udelay(1);
1588
1589 SEL_PRINTK("scsi%d: selecting target %d\n", HOSTNO, cmd->device->id);
1590
1591
1592
1593
1594
1595
1596 timeout = jiffies + 25;
1597
1598
1599
1600
1601
1602
1603
1604#if 0
1605
1606
1607
1608
1609
1610
1611
1612 while (time_before(jiffies, timeout) &&
1613 !(NCR5380_read(STATUS_REG) & (SR_BSY | SR_IO)))
1614 ;
1615
1616 if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) == (SR_SEL | SR_IO)) {
1617 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
1618 NCR5380_reselect(instance);
1619 printk(KERN_ERR "scsi%d: reselection after won arbitration?\n",
1620 HOSTNO);
1621 NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
1622 return -1;
1623 }
1624#else
1625 while (time_before(jiffies, timeout) && !(NCR5380_read(STATUS_REG) & SR_BSY))
1626 ;
1627#endif
1628
1629
1630
1631
1632
1633
1634
1635 udelay(1);
1636
1637 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
1638
1639 if (!(NCR5380_read(STATUS_REG) & SR_BSY)) {
1640 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
1641 if (hostdata->targets_present & (1 << cmd->device->id)) {
1642 printk(KERN_ERR "scsi%d: weirdness\n", HOSTNO);
1643 if (hostdata->restart_select)
1644 printk(KERN_NOTICE "\trestart select\n");
1645 NCR_PRINT(NDEBUG_ANY);
1646 NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
1647 return -1;
1648 }
1649 cmd->result = DID_BAD_TARGET << 16;
1650#ifdef NCR5380_STATS
1651 collect_stats(hostdata, cmd);
1652#endif
1653#ifdef SUPPORT_TAGS
1654 cmd_free_tag(cmd);
1655#endif
1656 cmd->scsi_done(cmd);
1657 NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
1658 SEL_PRINTK("scsi%d: target did not respond within 250ms\n", HOSTNO);
1659 NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
1660 return 0;
1661 }
1662
1663 hostdata->targets_present |= (1 << cmd->device->id);
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681 while (!(NCR5380_read(STATUS_REG) & SR_REQ))
1682 ;
1683
1684 SEL_PRINTK("scsi%d: target %d selected, going into MESSAGE OUT phase.\n",
1685 HOSTNO, cmd->device->id);
1686 tmp[0] = IDENTIFY(1, cmd->device->lun);
1687
1688#ifdef SUPPORT_TAGS
1689 if (cmd->tag != TAG_NONE) {
1690 tmp[1] = hostdata->last_message = SIMPLE_QUEUE_TAG;
1691 tmp[2] = cmd->tag;
1692 len = 3;
1693 } else
1694 len = 1;
1695#else
1696 len = 1;
1697 cmd->tag = 0;
1698#endif
1699
1700
1701 data = tmp;
1702 phase = PHASE_MSGOUT;
1703 NCR5380_transfer_pio(instance, &phase, &len, &data);
1704 SEL_PRINTK("scsi%d: nexus established.\n", HOSTNO);
1705
1706 hostdata->connected = cmd;
1707#ifndef SUPPORT_TAGS
1708 hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);
1709#endif
1710
1711 initialize_SCp(cmd);
1712
1713 return 0;
1714}
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741static int NCR5380_transfer_pio(struct Scsi_Host *instance,
1742 unsigned char *phase, int *count,
1743 unsigned char **data)
1744{
1745 register unsigned char p = *phase, tmp;
1746 register int c = *count;
1747 register unsigned char *d = *data;
1748
1749
1750
1751
1752
1753
1754
1755 NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p));
1756
1757 do {
1758
1759
1760
1761
1762 while (!((tmp = NCR5380_read(STATUS_REG)) & SR_REQ))
1763 ;
1764
1765 HSH_PRINTK("scsi%d: REQ detected\n", HOSTNO);
1766
1767
1768 if ((tmp & PHASE_MASK) != p) {
1769 PIO_PRINTK("scsi%d: phase mismatch\n", HOSTNO);
1770 NCR_PRINT_PHASE(NDEBUG_PIO);
1771 break;
1772 }
1773
1774
1775 if (!(p & SR_IO))
1776 NCR5380_write(OUTPUT_DATA_REG, *d);
1777 else
1778 *d = NCR5380_read(CURRENT_SCSI_DATA_REG);
1779
1780 ++d;
1781
1782
1783
1784
1785
1786
1787
1788
1789 if (!(p & SR_IO)) {
1790 if (!((p & SR_MSG) && c > 1)) {
1791 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA);
1792 NCR_PRINT(NDEBUG_PIO);
1793 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
1794 ICR_ASSERT_DATA | ICR_ASSERT_ACK);
1795 } else {
1796 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
1797 ICR_ASSERT_DATA | ICR_ASSERT_ATN);
1798 NCR_PRINT(NDEBUG_PIO);
1799 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
1800 ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_ACK);
1801 }
1802 } else {
1803 NCR_PRINT(NDEBUG_PIO);
1804 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ACK);
1805 }
1806
1807 while (NCR5380_read(STATUS_REG) & SR_REQ)
1808 ;
1809
1810 HSH_PRINTK("scsi%d: req false, handshake complete\n", HOSTNO);
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823 if (!(p == PHASE_MSGIN && c == 1)) {
1824 if (p == PHASE_MSGOUT && c > 1)
1825 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
1826 else
1827 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
1828 }
1829 } while (--c);
1830
1831 PIO_PRINTK("scsi%d: residual %d\n", HOSTNO, c);
1832
1833 *count = c;
1834 *data = d;
1835 tmp = NCR5380_read(STATUS_REG);
1836
1837
1838
1839
1840 if ((tmp & SR_REQ) || (p == PHASE_MSGIN && c == 0))
1841 *phase = tmp & PHASE_MASK;
1842 else
1843 *phase = PHASE_UNKNOWN;
1844
1845 if (!c || (*phase == p))
1846 return 0;
1847 else
1848 return -1;
1849}
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860static int do_abort(struct Scsi_Host *host)
1861{
1862 unsigned char tmp, *msgptr, phase;
1863 int len;
1864
1865
1866 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878 while (!((tmp = NCR5380_read(STATUS_REG)) & SR_REQ))
1879 ;
1880
1881 NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp));
1882
1883 if ((tmp & PHASE_MASK) != PHASE_MSGOUT) {
1884 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN |
1885 ICR_ASSERT_ACK);
1886 while (NCR5380_read(STATUS_REG) & SR_REQ)
1887 ;
1888 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
1889 }
1890
1891 tmp = ABORT;
1892 msgptr = &tmp;
1893 len = 1;
1894 phase = PHASE_MSGOUT;
1895 NCR5380_transfer_pio(host, &phase, &len, &msgptr);
1896
1897
1898
1899
1900
1901
1902 return len ? -1 : 0;
1903}
1904
1905#if defined(REAL_DMA)
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926static int NCR5380_transfer_dma(struct Scsi_Host *instance,
1927 unsigned char *phase, int *count,
1928 unsigned char **data)
1929{
1930 SETUP_HOSTDATA(instance);
1931 register int c = *count;
1932 register unsigned char p = *phase;
1933 register unsigned char *d = *data;
1934 unsigned char tmp;
1935 unsigned long flags;
1936
1937 if ((tmp = (NCR5380_read(STATUS_REG) & PHASE_MASK)) != p) {
1938 *phase = tmp;
1939 return -1;
1940 }
1941
1942 if (atari_read_overruns && (p & SR_IO))
1943 c -= atari_read_overruns;
1944
1945 DMA_PRINTK("scsi%d: initializing DMA for %s, %d bytes %s %p\n",
1946 HOSTNO, (p & SR_IO) ? "reading" : "writing",
1947 c, (p & SR_IO) ? "to" : "from", d);
1948
1949 NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p));
1950
1951#ifdef REAL_DMA
1952 NCR5380_write(MODE_REG, MR_BASE | MR_DMA_MODE | MR_ENABLE_EOP_INTR | MR_MONITOR_BSY);
1953#endif
1954
1955 if (IS_A_TT()) {
1956
1957
1958
1959 local_irq_save(flags);
1960 hostdata->dma_len = (p & SR_IO) ?
1961 NCR5380_dma_read_setup(instance, d, c) :
1962 NCR5380_dma_write_setup(instance, d, c);
1963 local_irq_restore(flags);
1964 }
1965
1966 if (p & SR_IO)
1967 NCR5380_write(START_DMA_INITIATOR_RECEIVE_REG, 0);
1968 else {
1969 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA);
1970 NCR5380_write(START_DMA_SEND_REG, 0);
1971 }
1972
1973 if (!IS_A_TT()) {
1974
1975
1976
1977 local_irq_save(flags);
1978 hostdata->dma_len = (p & SR_IO) ?
1979 NCR5380_dma_read_setup(instance, d, c) :
1980 NCR5380_dma_write_setup(instance, d, c);
1981 local_irq_restore(flags);
1982 }
1983 return 0;
1984}
1985#endif
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004static void NCR5380_information_transfer(struct Scsi_Host *instance)
2005{
2006 SETUP_HOSTDATA(instance);
2007 unsigned long flags;
2008 unsigned char msgout = NOP;
2009 int sink = 0;
2010 int len;
2011#if defined(REAL_DMA)
2012 int transfersize;
2013#endif
2014 unsigned char *data;
2015 unsigned char phase, tmp, extended_msg[10], old_phase = 0xff;
2016 Scsi_Cmnd *cmd = (Scsi_Cmnd *) hostdata->connected;
2017
2018 while (1) {
2019 tmp = NCR5380_read(STATUS_REG);
2020
2021 if (tmp & SR_REQ) {
2022 phase = (tmp & PHASE_MASK);
2023 if (phase != old_phase) {
2024 old_phase = phase;
2025 NCR_PRINT_PHASE(NDEBUG_INFORMATION);
2026 }
2027
2028 if (sink && (phase != PHASE_MSGOUT)) {
2029 NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp));
2030
2031 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN |
2032 ICR_ASSERT_ACK);
2033 while (NCR5380_read(STATUS_REG) & SR_REQ)
2034 ;
2035 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
2036 ICR_ASSERT_ATN);
2037 sink = 0;
2038 continue;
2039 }
2040
2041 switch (phase) {
2042 case PHASE_DATAOUT:
2043#if (NDEBUG & NDEBUG_NO_DATAOUT)
2044 printk("scsi%d: NDEBUG_NO_DATAOUT set, attempted DATAOUT "
2045 "aborted\n", HOSTNO);
2046 sink = 1;
2047 do_abort(instance);
2048 cmd->result = DID_ERROR << 16;
2049 cmd->scsi_done(cmd);
2050 return;
2051#endif
2052 case PHASE_DATAIN:
2053
2054
2055
2056
2057
2058 if (!cmd->SCp.this_residual && cmd->SCp.buffers_residual) {
2059 ++cmd->SCp.buffer;
2060 --cmd->SCp.buffers_residual;
2061 cmd->SCp.this_residual = cmd->SCp.buffer->length;
2062 cmd->SCp.ptr = sg_virt(cmd->SCp.buffer);
2063
2064
2065
2066 merge_contiguous_buffers(cmd);
2067 INF_PRINTK("scsi%d: %d bytes and %d buffers left\n",
2068 HOSTNO, cmd->SCp.this_residual,
2069 cmd->SCp.buffers_residual);
2070 }
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087#if defined(REAL_DMA)
2088 if (!cmd->device->borken &&
2089 (transfersize = NCR5380_dma_xfer_len(instance,cmd,phase)) > 31) {
2090 len = transfersize;
2091 cmd->SCp.phase = phase;
2092 if (NCR5380_transfer_dma(instance, &phase,
2093 &len, (unsigned char **)&cmd->SCp.ptr)) {
2094
2095
2096
2097
2098 printk(KERN_NOTICE "scsi%d: switching target %d "
2099 "lun %d to slow handshake\n", HOSTNO,
2100 cmd->device->id, cmd->device->lun);
2101 cmd->device->borken = 1;
2102 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
2103 ICR_ASSERT_ATN);
2104 sink = 1;
2105 do_abort(instance);
2106 cmd->result = DID_ERROR << 16;
2107 cmd->scsi_done(cmd);
2108
2109 } else {
2110#ifdef REAL_DMA
2111
2112
2113
2114
2115
2116 return;
2117#else
2118 cmd->SCp.this_residual -= transfersize - len;
2119#endif
2120 }
2121 } else
2122#endif
2123 NCR5380_transfer_pio(instance, &phase,
2124 (int *)&cmd->SCp.this_residual,
2125 (unsigned char **)&cmd->SCp.ptr);
2126 break;
2127 case PHASE_MSGIN:
2128 len = 1;
2129 data = &tmp;
2130 NCR5380_write(SELECT_ENABLE_REG, 0);
2131 NCR5380_transfer_pio(instance, &phase, &len, &data);
2132 cmd->SCp.Message = tmp;
2133
2134 switch (tmp) {
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145#ifdef LINKED
2146 case LINKED_CMD_COMPLETE:
2147 case LINKED_FLG_CMD_COMPLETE:
2148
2149 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
2150
2151 LNK_PRINTK("scsi%d: target %d lun %d linked command "
2152 "complete.\n", HOSTNO, cmd->device->id, cmd->device->lun);
2153
2154
2155 NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
2156
2157
2158
2159
2160
2161
2162 if (!cmd->next_link) {
2163 printk(KERN_NOTICE "scsi%d: target %d lun %d "
2164 "linked command complete, no next_link\n",
2165 HOSTNO, cmd->device->id, cmd->device->lun);
2166 sink = 1;
2167 do_abort(instance);
2168 return;
2169 }
2170
2171 initialize_SCp(cmd->next_link);
2172
2173
2174 cmd->next_link->tag = cmd->tag;
2175 cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8);
2176 LNK_PRINTK("scsi%d: target %d lun %d linked request "
2177 "done, calling scsi_done().\n",
2178 HOSTNO, cmd->device->id, cmd->device->lun);
2179#ifdef NCR5380_STATS
2180 collect_stats(hostdata, cmd);
2181#endif
2182 cmd->scsi_done(cmd);
2183 cmd = hostdata->connected;
2184 break;
2185#endif
2186 case ABORT:
2187 case COMMAND_COMPLETE:
2188
2189 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
2190
2191 falcon_dont_release++;
2192 hostdata->connected = NULL;
2193 QU_PRINTK("scsi%d: command for target %d, lun %d "
2194 "completed\n", HOSTNO, cmd->device->id, cmd->device->lun);
2195#ifdef SUPPORT_TAGS
2196 cmd_free_tag(cmd);
2197 if (status_byte(cmd->SCp.Status) == QUEUE_FULL) {
2198
2199
2200
2201
2202
2203
2204
2205
2206 TAG_ALLOC *ta = &TagAlloc[cmd->device->id][cmd->device->lun];
2207 TAG_PRINTK("scsi%d: target %d lun %d returned "
2208 "QUEUE_FULL after %d commands\n",
2209 HOSTNO, cmd->device->id, cmd->device->lun,
2210 ta->nr_allocated);
2211 if (ta->queue_size > ta->nr_allocated)
2212 ta->nr_allocated = ta->queue_size;
2213 }
2214#else
2215 hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
2216#endif
2217
2218 NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236 if (cmd->cmnd[0] != REQUEST_SENSE)
2237 cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8);
2238 else if (status_byte(cmd->SCp.Status) != GOOD)
2239 cmd->result = (cmd->result & 0x00ffff) | (DID_ERROR << 16);
2240
2241#ifdef AUTOSENSE
2242 if ((cmd->cmnd[0] == REQUEST_SENSE) &&
2243 hostdata->ses.cmd_len) {
2244 scsi_eh_restore_cmnd(cmd, &hostdata->ses);
2245 hostdata->ses.cmd_len = 0 ;
2246 }
2247
2248 if ((cmd->cmnd[0] != REQUEST_SENSE) &&
2249 (status_byte(cmd->SCp.Status) == CHECK_CONDITION)) {
2250 scsi_eh_prep_cmnd(cmd, &hostdata->ses, NULL, 0, ~0);
2251
2252 ASEN_PRINTK("scsi%d: performing request sense\n", HOSTNO);
2253
2254 local_irq_save(flags);
2255 LIST(cmd,hostdata->issue_queue);
2256 SET_NEXT(cmd, hostdata->issue_queue);
2257 hostdata->issue_queue = (Scsi_Cmnd *) cmd;
2258 local_irq_restore(flags);
2259 QU_PRINTK("scsi%d: REQUEST SENSE added to head of "
2260 "issue queue\n", H_NO(cmd));
2261 } else
2262#endif
2263 {
2264#ifdef NCR5380_STATS
2265 collect_stats(hostdata, cmd);
2266#endif
2267 cmd->scsi_done(cmd);
2268 }
2269
2270 NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
2271
2272
2273
2274
2275 NCR5380_write(TARGET_COMMAND_REG, 0);
2276
2277 while ((NCR5380_read(STATUS_REG) & SR_BSY) && !hostdata->connected)
2278 barrier();
2279
2280 falcon_dont_release--;
2281
2282
2283
2284
2285 falcon_release_lock_if_possible(hostdata);
2286 return;
2287 case MESSAGE_REJECT:
2288
2289 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
2290
2291 NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
2292 switch (hostdata->last_message) {
2293 case HEAD_OF_QUEUE_TAG:
2294 case ORDERED_QUEUE_TAG:
2295 case SIMPLE_QUEUE_TAG:
2296
2297
2298
2299
2300
2301
2302 cmd->device->tagged_supported = 0;
2303 hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);
2304 cmd->tag = TAG_NONE;
2305 TAG_PRINTK("scsi%d: target %d lun %d rejected "
2306 "QUEUE_TAG message; tagged queuing "
2307 "disabled\n",
2308 HOSTNO, cmd->device->id, cmd->device->lun);
2309 break;
2310 }
2311 break;
2312 case DISCONNECT:
2313
2314 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
2315 local_irq_save(flags);
2316 cmd->device->disconnect = 1;
2317 LIST(cmd,hostdata->disconnected_queue);
2318 SET_NEXT(cmd, hostdata->disconnected_queue);
2319 hostdata->connected = NULL;
2320 hostdata->disconnected_queue = cmd;
2321 local_irq_restore(flags);
2322 QU_PRINTK("scsi%d: command for target %d lun %d was "
2323 "moved from connected to the "
2324 "disconnected_queue\n", HOSTNO,
2325 cmd->device->id, cmd->device->lun);
2326
2327
2328
2329
2330 NCR5380_write(TARGET_COMMAND_REG, 0);
2331
2332
2333 NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
2334
2335 while ((NCR5380_read(STATUS_REG) & SR_BSY) && !hostdata->connected)
2336 barrier();
2337 return;
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348 case SAVE_POINTERS:
2349 case RESTORE_POINTERS:
2350
2351 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
2352
2353 NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
2354 break;
2355 case EXTENDED_MESSAGE:
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368 extended_msg[0] = EXTENDED_MESSAGE;
2369
2370 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
2371
2372 EXT_PRINTK("scsi%d: receiving extended message\n", HOSTNO);
2373
2374 len = 2;
2375 data = extended_msg + 1;
2376 phase = PHASE_MSGIN;
2377 NCR5380_transfer_pio(instance, &phase, &len, &data);
2378 EXT_PRINTK("scsi%d: length=%d, code=0x%02x\n", HOSTNO,
2379 (int)extended_msg[1], (int)extended_msg[2]);
2380
2381 if (!len && extended_msg[1] <=
2382 (sizeof(extended_msg) - 1)) {
2383
2384 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
2385 len = extended_msg[1] - 1;
2386 data = extended_msg + 3;
2387 phase = PHASE_MSGIN;
2388
2389 NCR5380_transfer_pio(instance, &phase, &len, &data);
2390 EXT_PRINTK("scsi%d: message received, residual %d\n",
2391 HOSTNO, len);
2392
2393 switch (extended_msg[2]) {
2394 case EXTENDED_SDTR:
2395 case EXTENDED_WDTR:
2396 case EXTENDED_MODIFY_DATA_POINTER:
2397 case EXTENDED_EXTENDED_IDENTIFY:
2398 tmp = 0;
2399 }
2400 } else if (len) {
2401 printk(KERN_NOTICE "scsi%d: error receiving "
2402 "extended message\n", HOSTNO);
2403 tmp = 0;
2404 } else {
2405 printk(KERN_NOTICE "scsi%d: extended message "
2406 "code %02x length %d is too long\n",
2407 HOSTNO, extended_msg[2], extended_msg[1]);
2408 tmp = 0;
2409 }
2410
2411
2412
2413
2414
2415
2416 default:
2417 if (!tmp) {
2418 printk(KERN_DEBUG "scsi%d: rejecting message ", HOSTNO);
2419 spi_print_msg(extended_msg);
2420 printk("\n");
2421 } else if (tmp != EXTENDED_MESSAGE)
2422 printk(KERN_DEBUG "scsi%d: rejecting unknown "
2423 "message %02x from target %d, lun %d\n",
2424 HOSTNO, tmp, cmd->device->id, cmd->device->lun);
2425 else
2426 printk(KERN_DEBUG "scsi%d: rejecting unknown "
2427 "extended message "
2428 "code %02x, length %d from target %d, lun %d\n",
2429 HOSTNO, extended_msg[1], extended_msg[0],
2430 cmd->device->id, cmd->device->lun);
2431
2432
2433 msgout = MESSAGE_REJECT;
2434 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
2435 break;
2436 }
2437 break;
2438 case PHASE_MSGOUT:
2439 len = 1;
2440 data = &msgout;
2441 hostdata->last_message = msgout;
2442 NCR5380_transfer_pio(instance, &phase, &len, &data);
2443 if (msgout == ABORT) {
2444#ifdef SUPPORT_TAGS
2445 cmd_free_tag(cmd);
2446#else
2447 hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
2448#endif
2449 hostdata->connected = NULL;
2450 cmd->result = DID_ERROR << 16;
2451#ifdef NCR5380_STATS
2452 collect_stats(hostdata, cmd);
2453#endif
2454 cmd->scsi_done(cmd);
2455 NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
2456 falcon_release_lock_if_possible(hostdata);
2457 return;
2458 }
2459 msgout = NOP;
2460 break;
2461 case PHASE_CMDOUT:
2462 len = cmd->cmd_len;
2463 data = cmd->cmnd;
2464
2465
2466
2467
2468
2469 NCR5380_transfer_pio(instance, &phase, &len, &data);
2470 break;
2471 case PHASE_STATIN:
2472 len = 1;
2473 data = &tmp;
2474 NCR5380_transfer_pio(instance, &phase, &len, &data);
2475 cmd->SCp.Status = tmp;
2476 break;
2477 default:
2478 printk("scsi%d: unknown phase\n", HOSTNO);
2479 NCR_PRINT(NDEBUG_ANY);
2480 }
2481 }
2482 }
2483}
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497static void NCR5380_reselect(struct Scsi_Host *instance)
2498{
2499 SETUP_HOSTDATA(instance);
2500 unsigned char target_mask;
2501 unsigned char lun, phase;
2502 int len;
2503#ifdef SUPPORT_TAGS
2504 unsigned char tag;
2505#endif
2506 unsigned char msg[3];
2507 unsigned char *data;
2508 Scsi_Cmnd *tmp = NULL, *prev;
2509
2510
2511
2512
2513
2514
2515
2516 NCR5380_write(MODE_REG, MR_BASE);
2517 hostdata->restart_select = 1;
2518
2519 target_mask = NCR5380_read(CURRENT_SCSI_DATA_REG) & ~(hostdata->id_mask);
2520
2521 RSL_PRINTK("scsi%d: reselect\n", HOSTNO);
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_BSY);
2533
2534 while (NCR5380_read(STATUS_REG) & SR_SEL)
2535 ;
2536 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
2537
2538
2539
2540
2541
2542 while (!(NCR5380_read(STATUS_REG) & SR_REQ))
2543 ;
2544
2545 len = 1;
2546 data = msg;
2547 phase = PHASE_MSGIN;
2548 NCR5380_transfer_pio(instance, &phase, &len, &data);
2549
2550 if (!(msg[0] & 0x80)) {
2551 printk(KERN_DEBUG "scsi%d: expecting IDENTIFY message, got ", HOSTNO);
2552 spi_print_msg(msg);
2553 do_abort(instance);
2554 return;
2555 }
2556 lun = (msg[0] & 0x07);
2557
2558#ifdef SUPPORT_TAGS
2559
2560
2561
2562
2563 tag = TAG_NONE;
2564 if (phase == PHASE_MSGIN && setup_use_tagged_queuing) {
2565
2566 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
2567 len = 2;
2568 data = msg + 1;
2569 if (!NCR5380_transfer_pio(instance, &phase, &len, &data) &&
2570 msg[1] == SIMPLE_QUEUE_TAG)
2571 tag = msg[2];
2572 TAG_PRINTK("scsi%d: target mask %02x, lun %d sent tag %d at "
2573 "reselection\n", HOSTNO, target_mask, lun, tag);
2574 }
2575#endif
2576
2577
2578
2579
2580
2581
2582 for (tmp = (Scsi_Cmnd *) hostdata->disconnected_queue, prev = NULL;
2583 tmp; prev = tmp, tmp = NEXT(tmp)) {
2584 if ((target_mask == (1 << tmp->device->id)) && (lun == tmp->device->lun)
2585#ifdef SUPPORT_TAGS
2586 && (tag == tmp->tag)
2587#endif
2588 ) {
2589
2590 falcon_dont_release++;
2591 if (prev) {
2592 REMOVE(prev, NEXT(prev), tmp, NEXT(tmp));
2593 SET_NEXT(prev, NEXT(tmp));
2594 } else {
2595 REMOVE(-1, hostdata->disconnected_queue, tmp, NEXT(tmp));
2596 hostdata->disconnected_queue = NEXT(tmp);
2597 }
2598 SET_NEXT(tmp, NULL);
2599 break;
2600 }
2601 }
2602
2603 if (!tmp) {
2604 printk(KERN_WARNING "scsi%d: warning: target bitmask %02x lun %d "
2605#ifdef SUPPORT_TAGS
2606 "tag %d "
2607#endif
2608 "not in disconnected_queue.\n",
2609 HOSTNO, target_mask, lun
2610#ifdef SUPPORT_TAGS
2611 , tag
2612#endif
2613 );
2614
2615
2616
2617
2618 do_abort(instance);
2619 return;
2620 }
2621
2622
2623 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
2624
2625 hostdata->connected = tmp;
2626 RSL_PRINTK("scsi%d: nexus established, target = %d, lun = %d, tag = %d\n",
2627 HOSTNO, tmp->device->id, tmp->device->lun, tmp->tag);
2628 falcon_dont_release--;
2629}
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649static
2650int NCR5380_abort(Scsi_Cmnd *cmd)
2651{
2652 struct Scsi_Host *instance = cmd->device->host;
2653 SETUP_HOSTDATA(instance);
2654 Scsi_Cmnd *tmp, **prev;
2655 unsigned long flags;
2656
2657 printk(KERN_NOTICE "scsi%d: aborting command\n", HOSTNO);
2658 scsi_print_command(cmd);
2659
2660 NCR5380_print_status(instance);
2661
2662 local_irq_save(flags);
2663
2664 if (!IS_A_TT() && !falcon_got_lock)
2665 printk(KERN_ERR "scsi%d: !!BINGO!! Falcon has no lock in NCR5380_abort\n",
2666 HOSTNO);
2667
2668 ABRT_PRINTK("scsi%d: abort called basr 0x%02x, sr 0x%02x\n", HOSTNO,
2669 NCR5380_read(BUS_AND_STATUS_REG),
2670 NCR5380_read(STATUS_REG));
2671
2672#if 1
2673
2674
2675
2676
2677
2678
2679 if (hostdata->connected == cmd) {
2680
2681 ABRT_PRINTK("scsi%d: aborting connected command\n", HOSTNO);
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699 if (do_abort(instance) == 0) {
2700 hostdata->aborted = 1;
2701 hostdata->connected = NULL;
2702 cmd->result = DID_ABORT << 16;
2703#ifdef SUPPORT_TAGS
2704 cmd_free_tag(cmd);
2705#else
2706 hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
2707#endif
2708 local_irq_restore(flags);
2709 cmd->scsi_done(cmd);
2710 falcon_release_lock_if_possible(hostdata);
2711 return SCSI_ABORT_SUCCESS;
2712 } else {
2713
2714 printk("scsi%d: abort of connected command failed!\n", HOSTNO);
2715 return SCSI_ABORT_ERROR;
2716 }
2717 }
2718#endif
2719
2720
2721
2722
2723
2724 for (prev = (Scsi_Cmnd **)&(hostdata->issue_queue),
2725 tmp = (Scsi_Cmnd *)hostdata->issue_queue;
2726 tmp; prev = NEXTADDR(tmp), tmp = NEXT(tmp)) {
2727 if (cmd == tmp) {
2728 REMOVE(5, *prev, tmp, NEXT(tmp));
2729 (*prev) = NEXT(tmp);
2730 SET_NEXT(tmp, NULL);
2731 tmp->result = DID_ABORT << 16;
2732 local_irq_restore(flags);
2733 ABRT_PRINTK("scsi%d: abort removed command from issue queue.\n",
2734 HOSTNO);
2735
2736
2737 tmp->scsi_done(tmp);
2738 falcon_release_lock_if_possible(hostdata);
2739 return SCSI_ABORT_SUCCESS;
2740 }
2741 }
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754 if (hostdata->connected) {
2755 local_irq_restore(flags);
2756 ABRT_PRINTK("scsi%d: abort failed, command connected.\n", HOSTNO);
2757 return SCSI_ABORT_SNOOZE;
2758 }
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785 for (tmp = (Scsi_Cmnd *) hostdata->disconnected_queue; tmp;
2786 tmp = NEXT(tmp)) {
2787 if (cmd == tmp) {
2788 local_irq_restore(flags);
2789 ABRT_PRINTK("scsi%d: aborting disconnected command.\n", HOSTNO);
2790
2791 if (NCR5380_select(instance, cmd, (int)cmd->tag))
2792 return SCSI_ABORT_BUSY;
2793
2794 ABRT_PRINTK("scsi%d: nexus reestablished.\n", HOSTNO);
2795
2796 do_abort(instance);
2797
2798 local_irq_save(flags);
2799 for (prev = (Scsi_Cmnd **)&(hostdata->disconnected_queue),
2800 tmp = (Scsi_Cmnd *)hostdata->disconnected_queue;
2801 tmp; prev = NEXTADDR(tmp), tmp = NEXT(tmp)) {
2802 if (cmd == tmp) {
2803 REMOVE(5, *prev, tmp, NEXT(tmp));
2804 *prev = NEXT(tmp);
2805 SET_NEXT(tmp, NULL);
2806 tmp->result = DID_ABORT << 16;
2807
2808
2809
2810
2811#ifdef SUPPORT_TAGS
2812 cmd_free_tag(tmp);
2813#else
2814 hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
2815#endif
2816 local_irq_restore(flags);
2817 tmp->scsi_done(tmp);
2818 falcon_release_lock_if_possible(hostdata);
2819 return SCSI_ABORT_SUCCESS;
2820 }
2821 }
2822 }
2823 }
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835 local_irq_restore(flags);
2836 printk(KERN_INFO "scsi%d: warning : SCSI command probably completed successfully before abortion\n", HOSTNO);
2837
2838
2839
2840
2841
2842 falcon_release_lock_if_possible(hostdata);
2843
2844 return SCSI_ABORT_NOT_RUNNING;
2845}
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857static int NCR5380_bus_reset(Scsi_Cmnd *cmd)
2858{
2859 SETUP_HOSTDATA(cmd->device->host);
2860 int i;
2861 unsigned long flags;
2862#if 1
2863 Scsi_Cmnd *connected, *disconnected_queue;
2864#endif
2865
2866 if (!IS_A_TT() && !falcon_got_lock)
2867 printk(KERN_ERR "scsi%d: !!BINGO!! Falcon has no lock in NCR5380_reset\n",
2868 H_NO(cmd));
2869
2870 NCR5380_print_status(cmd->device->host);
2871
2872
2873 NCR5380_write(TARGET_COMMAND_REG,
2874 PHASE_SR_TO_TCR(NCR5380_read(STATUS_REG)));
2875
2876 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST);
2877 udelay(40);
2878
2879 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
2880 NCR5380_write(MODE_REG, MR_BASE);
2881 NCR5380_write(TARGET_COMMAND_REG, 0);
2882 NCR5380_write(SELECT_ENABLE_REG, 0);
2883
2884
2885 (void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
2886
2887#if 1
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897 local_irq_save(flags);
2898 connected = (Scsi_Cmnd *)hostdata->connected;
2899 hostdata->connected = NULL;
2900 disconnected_queue = (Scsi_Cmnd *)hostdata->disconnected_queue;
2901 hostdata->disconnected_queue = NULL;
2902#ifdef SUPPORT_TAGS
2903 free_all_tags();
2904#endif
2905 for (i = 0; i < 8; ++i)
2906 hostdata->busy[i] = 0;
2907#ifdef REAL_DMA
2908 hostdata->dma_len = 0;
2909#endif
2910 local_irq_restore(flags);
2911
2912
2913
2914
2915
2916
2917 if ((cmd = connected)) {
2918 ABRT_PRINTK("scsi%d: reset aborted a connected command\n", H_NO(cmd));
2919 cmd->result = (cmd->result & 0xffff) | (DID_RESET << 16);
2920 cmd->scsi_done(cmd);
2921 }
2922
2923 for (i = 0; (cmd = disconnected_queue); ++i) {
2924 disconnected_queue = NEXT(cmd);
2925 SET_NEXT(cmd, NULL);
2926 cmd->result = (cmd->result & 0xffff) | (DID_RESET << 16);
2927 cmd->scsi_done(cmd);
2928 }
2929 if (i > 0)
2930 ABRT_PRINTK("scsi: reset aborted %d disconnected command(s)\n", i);
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943 return SCSI_RESET_SUCCESS | SCSI_RESET_BUS_RESET;
2944#else
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969 if (hostdata->issue_queue)
2970 ABRT_PRINTK("scsi%d: reset aborted issued command(s)\n", H_NO(cmd));
2971 if (hostdata->connected)
2972 ABRT_PRINTK("scsi%d: reset aborted a connected command\n", H_NO(cmd));
2973 if (hostdata->disconnected_queue)
2974 ABRT_PRINTK("scsi%d: reset aborted disconnected command(s)\n", H_NO(cmd));
2975
2976 local_irq_save(flags);
2977 hostdata->issue_queue = NULL;
2978 hostdata->connected = NULL;
2979 hostdata->disconnected_queue = NULL;
2980#ifdef SUPPORT_TAGS
2981 free_all_tags();
2982#endif
2983 for (i = 0; i < 8; ++i)
2984 hostdata->busy[i] = 0;
2985#ifdef REAL_DMA
2986 hostdata->dma_len = 0;
2987#endif
2988 local_irq_restore(flags);
2989
2990
2991 return SCSI_RESET_WAKEUP | SCSI_RESET_BUS_RESET;
2992#endif
2993}
2994