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