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