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