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