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