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