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