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