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 lprint_Scsi_Cmnd(Scsi_Cmnd *cmd)
665{
666 int i, s;
667 unsigned char *command;
668 printk("scsi%d: destination target %d, lun %d\n",
669 H_NO(cmd), cmd->device->id, cmd->device->lun);
670 printk(KERN_CONT " command = ");
671 command = cmd->cmnd;
672 printk(KERN_CONT "%2d (0x%02x)", command[0], command[0]);
673 for (i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i)
674 printk(KERN_CONT " %02x", command[i]);
675 printk("\n");
676}
677
678static void NCR5380_print_status(struct Scsi_Host *instance)
679{
680 struct NCR5380_hostdata *hostdata;
681 Scsi_Cmnd *ptr;
682 unsigned long flags;
683
684 NCR_PRINT(NDEBUG_ANY);
685 NCR_PRINT_PHASE(NDEBUG_ANY);
686
687 hostdata = (struct NCR5380_hostdata *)instance->hostdata;
688
689 printk("\nNCR5380 core release=%d.\n", NCR5380_PUBLIC_RELEASE);
690 local_irq_save(flags);
691 printk("NCR5380: coroutine is%s running.\n",
692 main_running ? "" : "n't");
693 if (!hostdata->connected)
694 printk("scsi%d: no currently connected command\n", HOSTNO);
695 else
696 lprint_Scsi_Cmnd((Scsi_Cmnd *) hostdata->connected);
697 printk("scsi%d: issue_queue\n", HOSTNO);
698 for (ptr = (Scsi_Cmnd *)hostdata->issue_queue; ptr; ptr = NEXT(ptr))
699 lprint_Scsi_Cmnd(ptr);
700
701 printk("scsi%d: disconnected_queue\n", HOSTNO);
702 for (ptr = (Scsi_Cmnd *) hostdata->disconnected_queue; ptr;
703 ptr = NEXT(ptr))
704 lprint_Scsi_Cmnd(ptr);
705
706 local_irq_restore(flags);
707 printk("\n");
708}
709
710static void show_Scsi_Cmnd(Scsi_Cmnd *cmd, struct seq_file *m)
711{
712 int i, s;
713 unsigned char *command;
714 seq_printf(m, "scsi%d: destination target %d, lun %d\n",
715 H_NO(cmd), cmd->device->id, cmd->device->lun);
716 seq_printf(m, " command = ");
717 command = cmd->cmnd;
718 seq_printf(m, "%2d (0x%02x)", command[0], command[0]);
719 for (i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i)
720 seq_printf(m, " %02x", command[i]);
721 seq_printf(m, "\n");
722}
723
724static int NCR5380_show_info(struct seq_file *m, struct Scsi_Host *instance)
725{
726 struct NCR5380_hostdata *hostdata;
727 Scsi_Cmnd *ptr;
728 unsigned long flags;
729
730 hostdata = (struct NCR5380_hostdata *)instance->hostdata;
731
732 seq_printf(m, "NCR5380 core release=%d.\n", NCR5380_PUBLIC_RELEASE);
733 local_irq_save(flags);
734 seq_printf(m, "NCR5380: coroutine is%s running.\n",
735 main_running ? "" : "n't");
736 if (!hostdata->connected)
737 seq_printf(m, "scsi%d: no currently connected command\n", HOSTNO);
738 else
739 show_Scsi_Cmnd((Scsi_Cmnd *) hostdata->connected, m);
740 seq_printf(m, "scsi%d: issue_queue\n", HOSTNO);
741 for (ptr = (Scsi_Cmnd *)hostdata->issue_queue; ptr; ptr = NEXT(ptr))
742 show_Scsi_Cmnd(ptr, m);
743
744 seq_printf(m, "scsi%d: disconnected_queue\n", HOSTNO);
745 for (ptr = (Scsi_Cmnd *) hostdata->disconnected_queue; ptr;
746 ptr = NEXT(ptr))
747 show_Scsi_Cmnd(ptr, m);
748
749 local_irq_restore(flags);
750 return 0;
751}
752
753
754
755
756
757
758
759
760
761
762
763
764
765static int __init NCR5380_init(struct Scsi_Host *instance, int flags)
766{
767 int i;
768 SETUP_HOSTDATA(instance);
769
770 NCR5380_all_init();
771
772 hostdata->aborted = 0;
773 hostdata->id_mask = 1 << instance->this_id;
774 hostdata->id_higher_mask = 0;
775 for (i = hostdata->id_mask; i <= 0x80; i <<= 1)
776 if (i > hostdata->id_mask)
777 hostdata->id_higher_mask |= i;
778 for (i = 0; i < 8; ++i)
779 hostdata->busy[i] = 0;
780#ifdef SUPPORT_TAGS
781 init_tags();
782#endif
783#if defined (REAL_DMA)
784 hostdata->dma_len = 0;
785#endif
786 hostdata->targets_present = 0;
787 hostdata->connected = NULL;
788 hostdata->issue_queue = NULL;
789 hostdata->disconnected_queue = NULL;
790 hostdata->flags = FLAG_CHECK_LAST_BYTE_SENT;
791
792 if (!the_template) {
793 the_template = instance->hostt;
794 first_instance = instance;
795 }
796
797
798#ifndef AUTOSENSE
799 if ((instance->cmd_per_lun > 1) || (instance->can_queue > 1))
800 printk("scsi%d: WARNING : support for multiple outstanding commands enabled\n"
801 " without AUTOSENSE option, contingent allegiance conditions may\n"
802 " be incorrectly cleared.\n", HOSTNO);
803#endif
804
805 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
806 NCR5380_write(MODE_REG, MR_BASE);
807 NCR5380_write(TARGET_COMMAND_REG, 0);
808 NCR5380_write(SELECT_ENABLE_REG, 0);
809
810 return 0;
811}
812
813static void NCR5380_exit(struct Scsi_Host *instance)
814{
815
816}
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837static int NCR5380_queue_command_lck(struct scsi_cmnd *cmd,
838 void (*done)(struct scsi_cmnd *))
839{
840 SETUP_HOSTDATA(cmd->device->host);
841 struct scsi_cmnd *tmp;
842 unsigned long flags;
843
844#if (NDEBUG & NDEBUG_NO_WRITE)
845 switch (cmd->cmnd[0]) {
846 case WRITE_6:
847 case WRITE_10:
848 printk(KERN_NOTICE "scsi%d: WRITE attempted with NO_WRITE debugging flag set\n",
849 H_NO(cmd));
850 cmd->result = (DID_ERROR << 16);
851 done(cmd);
852 return 0;
853 }
854#endif
855
856
857#ifdef NCR5380_STATS
858# if 0
859 if (!hostdata->connected && !hostdata->issue_queue &&
860 !hostdata->disconnected_queue) {
861 hostdata->timebase = jiffies;
862 }
863# endif
864# ifdef NCR5380_STAT_LIMIT
865 if (scsi_bufflen(cmd) > NCR5380_STAT_LIMIT)
866# endif
867 switch (cmd->cmnd[0])
868 {
869 case WRITE:
870 case WRITE_6:
871 case WRITE_10:
872 hostdata->time_write[cmd->device->id] -= (jiffies - hostdata->timebase);
873 hostdata->bytes_write[cmd->device->id] += scsi_bufflen(cmd);
874 hostdata->pendingw++;
875 break;
876 case READ:
877 case READ_6:
878 case READ_10:
879 hostdata->time_read[cmd->device->id] -= (jiffies - hostdata->timebase);
880 hostdata->bytes_read[cmd->device->id] += scsi_bufflen(cmd);
881 hostdata->pendingr++;
882 break;
883 }
884#endif
885
886
887
888
889
890
891 SET_NEXT(cmd, NULL);
892 cmd->scsi_done = done;
893
894 cmd->result = 0;
895
896
897
898
899
900
901
902
903
904 local_irq_save(flags);
905
906
907
908
909
910
911
912
913
914
915
916
917 if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) {
918 LIST(cmd, hostdata->issue_queue);
919 SET_NEXT(cmd, hostdata->issue_queue);
920 hostdata->issue_queue = cmd;
921 } else {
922 for (tmp = (struct scsi_cmnd *)hostdata->issue_queue;
923 NEXT(tmp); tmp = NEXT(tmp))
924 ;
925 LIST(cmd, tmp);
926 SET_NEXT(tmp, cmd);
927 }
928
929 local_irq_restore(flags);
930
931 QU_PRINTK("scsi%d: command added to %s of queue\n", H_NO(cmd),
932 (cmd->cmnd[0] == REQUEST_SENSE) ? "head" : "tail");
933
934
935
936
937
938
939
940
941 if (in_interrupt() || ((flags >> 8) & 7) >= 6)
942 queue_main();
943 else
944 NCR5380_main(NULL);
945 return 0;
946}
947
948static DEF_SCSI_QCMD(NCR5380_queue_command)
949
950
951
952
953
954
955
956
957
958
959
960
961
962static void NCR5380_main (struct work_struct *bl)
963{
964 struct scsi_cmnd *tmp, *prev;
965 struct Scsi_Host *instance = first_instance;
966 struct NCR5380_hostdata *hostdata = HOSTDATA(instance);
967 int done;
968 unsigned long flags;
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991 if (main_running)
992 return;
993 main_running = 1;
994
995 local_save_flags(flags);
996 do {
997 local_irq_disable();
998 done = 1;
999
1000 if (!hostdata->connected) {
1001 MAIN_PRINTK( "scsi%d: not connected\n", HOSTNO );
1002
1003
1004
1005
1006#if (NDEBUG & NDEBUG_LISTS)
1007 for (tmp = (struct scsi_cmnd *) hostdata->issue_queue, prev = NULL;
1008 tmp && (tmp != prev); prev = tmp, tmp = NEXT(tmp))
1009 ;
1010 if ((tmp == prev) && tmp) printk(" LOOP\n");
1011#endif
1012 for (tmp = (struct scsi_cmnd *) hostdata->issue_queue,
1013 prev = NULL; tmp; prev = tmp, tmp = NEXT(tmp) ) {
1014
1015#if (NDEBUG & NDEBUG_LISTS)
1016 if (prev != tmp)
1017 printk("MAIN tmp=%p target=%d busy=%d lun=%d\n",
1018 tmp, tmp->target, hostdata->busy[tmp->target],
1019 tmp->lun);
1020#endif
1021
1022
1023 if (
1024#ifdef SUPPORT_TAGS
1025 !is_lun_busy( tmp, tmp->cmnd[0] != REQUEST_SENSE)
1026#else
1027 !(hostdata->busy[tmp->device->id] & (1 << tmp->device->lun))
1028#endif
1029 ) {
1030
1031 local_irq_disable();
1032 if (prev) {
1033 REMOVE(prev, NEXT(prev), tmp, NEXT(tmp));
1034 SET_NEXT(prev, NEXT(tmp));
1035 } else {
1036 REMOVE(-1, hostdata->issue_queue, tmp, NEXT(tmp));
1037 hostdata->issue_queue = NEXT(tmp);
1038 }
1039 SET_NEXT(tmp, NULL);
1040
1041
1042 local_irq_restore(flags);
1043
1044
1045
1046
1047
1048
1049
1050 MAIN_PRINTK("scsi%d: main(): command for target %d "
1051 "lun %d removed from issue_queue\n",
1052 HOSTNO, tmp->target, tmp->lun);
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063#ifdef SUPPORT_TAGS
1064 cmd_get_tag( tmp, tmp->cmnd[0] != REQUEST_SENSE );
1065#endif
1066 if (!NCR5380_select(instance, tmp,
1067 (tmp->cmnd[0] == REQUEST_SENSE) ? TAG_NONE :
1068 TAG_NEXT)) {
1069 break;
1070 } else {
1071 local_irq_disable();
1072 LIST(tmp, hostdata->issue_queue);
1073 SET_NEXT(tmp, hostdata->issue_queue);
1074 hostdata->issue_queue = tmp;
1075#ifdef SUPPORT_TAGS
1076 cmd_free_tag( tmp );
1077#endif
1078 local_irq_restore(flags);
1079 MAIN_PRINTK("scsi%d: main(): select() failed, "
1080 "returned to issue_queue\n", HOSTNO);
1081 if (hostdata->connected)
1082 break;
1083 }
1084 }
1085 }
1086 }
1087 if (hostdata->connected
1088#ifdef REAL_DMA
1089 && !hostdata->dma_len
1090#endif
1091 ) {
1092 local_irq_restore(flags);
1093 MAIN_PRINTK("scsi%d: main: performing information transfer\n",
1094 HOSTNO);
1095 NCR5380_information_transfer(instance);
1096 MAIN_PRINTK("scsi%d: main: done set false\n", HOSTNO);
1097 done = 0;
1098 }
1099 } while (!done);
1100
1101
1102
1103
1104 main_running = 0;
1105 local_irq_restore(flags);
1106}
1107
1108
1109#ifdef REAL_DMA
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120static void NCR5380_dma_complete( struct Scsi_Host *instance )
1121{
1122 SETUP_HOSTDATA(instance);
1123 int transfered;
1124 unsigned char **data;
1125 volatile int *count;
1126
1127 if (!hostdata->connected) {
1128 printk(KERN_WARNING "scsi%d: received end of DMA interrupt with "
1129 "no connected cmd\n", HOSTNO);
1130 return;
1131 }
1132
1133 DMA_PRINTK("scsi%d: real DMA transfer complete, basr 0x%X, sr 0x%X\n",
1134 HOSTNO, NCR5380_read(BUS_AND_STATUS_REG),
1135 NCR5380_read(STATUS_REG));
1136
1137 if((sun3scsi_dma_finish(rq_data_dir(hostdata->connected->request)))) {
1138 printk("scsi%d: overrun in UDC counter -- not prepared to deal with this!\n", HOSTNO);
1139 printk("please e-mail sammy@sammy.net with a description of how this\n");
1140 printk("error was produced.\n");
1141 BUG();
1142 }
1143
1144
1145 if((NCR5380_read(BUS_AND_STATUS_REG) & (BASR_PHASE_MATCH |
1146 BASR_ACK)) ==
1147 (BASR_PHASE_MATCH | BASR_ACK)) {
1148 printk("scsi%d: BASR %02x\n", HOSTNO, NCR5380_read(BUS_AND_STATUS_REG));
1149 printk("scsi%d: bus stuck in data phase -- probably a single byte "
1150 "overrun!\n", HOSTNO);
1151 printk("not prepared for this error!\n");
1152 printk("please e-mail sammy@sammy.net with a description of how this\n");
1153 printk("error was produced.\n");
1154 BUG();
1155 }
1156
1157
1158
1159 (void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
1160 NCR5380_write(MODE_REG, MR_BASE);
1161 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
1162
1163 transfered = hostdata->dma_len - NCR5380_dma_residual(instance);
1164 hostdata->dma_len = 0;
1165
1166 data = (unsigned char **) &(hostdata->connected->SCp.ptr);
1167 count = &(hostdata->connected->SCp.this_residual);
1168 *data += transfered;
1169 *count -= transfered;
1170
1171}
1172#endif
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186static irqreturn_t NCR5380_intr (int irq, void *dev_id)
1187{
1188 struct Scsi_Host *instance = first_instance;
1189 int done = 1, handled = 0;
1190 unsigned char basr;
1191
1192 INT_PRINTK("scsi%d: NCR5380 irq triggered\n", HOSTNO);
1193
1194
1195 basr = NCR5380_read(BUS_AND_STATUS_REG);
1196 INT_PRINTK("scsi%d: BASR=%02x\n", HOSTNO, basr);
1197
1198 if (basr & BASR_IRQ) {
1199 NCR_PRINT(NDEBUG_INTR);
1200 if ((NCR5380_read(STATUS_REG) & (SR_SEL|SR_IO)) == (SR_SEL|SR_IO)) {
1201 done = 0;
1202
1203 INT_PRINTK("scsi%d: SEL interrupt\n", HOSTNO);
1204 NCR5380_reselect(instance);
1205 (void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
1206 }
1207 else if (basr & BASR_PARITY_ERROR) {
1208 INT_PRINTK("scsi%d: PARITY interrupt\n", HOSTNO);
1209 (void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
1210 }
1211 else if ((NCR5380_read(STATUS_REG) & SR_RST) == SR_RST) {
1212 INT_PRINTK("scsi%d: RESET interrupt\n", HOSTNO);
1213 (void)NCR5380_read(RESET_PARITY_INTERRUPT_REG);
1214 }
1215 else {
1216
1217
1218
1219
1220
1221#if defined(REAL_DMA)
1222
1223
1224
1225
1226
1227
1228 if ((NCR5380_read(MODE_REG) & MR_DMA_MODE) &&
1229 ((basr & BASR_END_DMA_TRANSFER) ||
1230 !(basr & BASR_PHASE_MATCH))) {
1231
1232 INT_PRINTK("scsi%d: PHASE MISM or EOP interrupt\n", HOSTNO);
1233 NCR5380_dma_complete( instance );
1234 done = 0;
1235
1236 } else
1237#endif
1238 {
1239
1240 if (basr & BASR_PHASE_MATCH)
1241 INT_PRINTK("scsi%d: unknown interrupt, "
1242 "BASR 0x%x, MR 0x%x, SR 0x%x\n",
1243 HOSTNO, basr, NCR5380_read(MODE_REG),
1244 NCR5380_read(STATUS_REG));
1245 (void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
1246#ifdef SUN3_SCSI_VME
1247 dregs->csr |= CSR_DMA_ENABLE;
1248#endif
1249 }
1250 }
1251 handled = 1;
1252 }
1253 else {
1254
1255 printk(KERN_NOTICE "scsi%d: interrupt without IRQ bit set in BASR, "
1256 "BASR 0x%X, MR 0x%X, SR 0x%x\n", HOSTNO, basr,
1257 NCR5380_read(MODE_REG), NCR5380_read(STATUS_REG));
1258 (void) NCR5380_read(RESET_PARITY_INTERRUPT_REG);
1259#ifdef SUN3_SCSI_VME
1260 dregs->csr |= CSR_DMA_ENABLE;
1261#endif
1262 }
1263
1264 if (!done) {
1265 INT_PRINTK("scsi%d: in int routine, calling main\n", HOSTNO);
1266
1267 queue_main();
1268 }
1269 return IRQ_RETVAL(handled);
1270}
1271
1272#ifdef NCR5380_STATS
1273static void collect_stats(struct NCR5380_hostdata *hostdata,
1274 struct scsi_cmnd *cmd)
1275{
1276# ifdef NCR5380_STAT_LIMIT
1277 if (scsi_bufflen(cmd) > NCR5380_STAT_LIMIT)
1278# endif
1279 switch (cmd->cmnd[0])
1280 {
1281 case WRITE:
1282 case WRITE_6:
1283 case WRITE_10:
1284 hostdata->time_write[cmd->device->id] += (jiffies - hostdata->timebase);
1285
1286 hostdata->pendingw--;
1287 break;
1288 case READ:
1289 case READ_6:
1290 case READ_10:
1291 hostdata->time_read[cmd->device->id] += (jiffies - hostdata->timebase);
1292
1293 hostdata->pendingr--;
1294 break;
1295 }
1296}
1297#endif
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd,
1331 int tag)
1332{
1333 SETUP_HOSTDATA(instance);
1334 unsigned char tmp[3], phase;
1335 unsigned char *data;
1336 int len;
1337 unsigned long timeout;
1338 unsigned long flags;
1339
1340 hostdata->restart_select = 0;
1341 NCR_PRINT(NDEBUG_ARBITRATION);
1342 ARB_PRINTK("scsi%d: starting arbitration, id = %d\n", HOSTNO,
1343 instance->this_id);
1344
1345
1346
1347
1348
1349
1350 local_irq_save(flags);
1351 if (hostdata->connected) {
1352 local_irq_restore(flags);
1353 return -1;
1354 }
1355 NCR5380_write(TARGET_COMMAND_REG, 0);
1356
1357
1358
1359
1360
1361
1362 NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask);
1363 NCR5380_write(MODE_REG, MR_ARBITRATE);
1364
1365 local_irq_restore(flags);
1366
1367
1368#ifdef NCR_TIMEOUT
1369 {
1370 unsigned long timeout = jiffies + 2*NCR_TIMEOUT;
1371
1372 while (!(NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_PROGRESS)
1373 && time_before(jiffies, timeout) && !hostdata->connected)
1374 ;
1375 if (time_after_eq(jiffies, timeout))
1376 {
1377 printk("scsi : arbitration timeout at %d\n", __LINE__);
1378 NCR5380_write(MODE_REG, MR_BASE);
1379 NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
1380 return -1;
1381 }
1382 }
1383#else
1384 while (!(NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_PROGRESS)
1385 && !hostdata->connected);
1386#endif
1387
1388 ARB_PRINTK("scsi%d: arbitration complete\n", HOSTNO);
1389
1390 if (hostdata->connected) {
1391 NCR5380_write(MODE_REG, MR_BASE);
1392 return -1;
1393 }
1394
1395
1396
1397
1398
1399
1400
1401 udelay(3);
1402
1403
1404 if ((NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) ||
1405 (NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_higher_mask) ||
1406 (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) ||
1407 hostdata->connected) {
1408 NCR5380_write(MODE_REG, MR_BASE);
1409 ARB_PRINTK("scsi%d: lost arbitration, deasserting MR_ARBITRATE\n",
1410 HOSTNO);
1411 return -1;
1412 }
1413
1414
1415
1416
1417 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_SEL |
1418 ICR_ASSERT_BSY ) ;
1419
1420 if ((NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) ||
1421 hostdata->connected) {
1422 NCR5380_write(MODE_REG, MR_BASE);
1423 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
1424 ARB_PRINTK("scsi%d: lost arbitration, deasserting ICR_ASSERT_SEL\n",
1425 HOSTNO);
1426 return -1;
1427 }
1428
1429
1430
1431
1432
1433
1434#ifdef CONFIG_ATARI_SCSI_TOSHIBA_DELAY
1435
1436 udelay(15);
1437#else
1438 udelay(2);
1439#endif
1440
1441 if (hostdata->connected) {
1442 NCR5380_write(MODE_REG, MR_BASE);
1443 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
1444 return -1;
1445 }
1446
1447 ARB_PRINTK("scsi%d: won arbitration\n", HOSTNO);
1448
1449
1450
1451
1452
1453
1454 NCR5380_write(OUTPUT_DATA_REG, (hostdata->id_mask | (1 << cmd->device->id)));
1455
1456
1457
1458
1459
1460
1461
1462 NCR5380_write(INITIATOR_COMMAND_REG, (ICR_BASE | ICR_ASSERT_BSY |
1463 ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_SEL ));
1464 NCR5380_write(MODE_REG, MR_BASE);
1465
1466
1467
1468
1469
1470
1471 if (hostdata->connected) {
1472 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
1473 return -1;
1474 }
1475
1476 NCR5380_write(SELECT_ENABLE_REG, 0);
1477
1478
1479
1480
1481
1482 udelay(1);
1483
1484
1485 NCR5380_write(INITIATOR_COMMAND_REG, (ICR_BASE | ICR_ASSERT_DATA |
1486 ICR_ASSERT_ATN | ICR_ASSERT_SEL));
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505 udelay(1);
1506
1507 SEL_PRINTK("scsi%d: selecting target %d\n", HOSTNO, cmd->device->id);
1508
1509
1510
1511
1512
1513
1514 timeout = jiffies + 25;
1515
1516
1517
1518
1519
1520
1521
1522#if 0
1523
1524
1525
1526
1527
1528
1529
1530 while (time_before(jiffies, timeout) && !(NCR5380_read(STATUS_REG) &
1531 (SR_BSY | SR_IO)));
1532
1533 if ((NCR5380_read(STATUS_REG) & (SR_SEL | SR_IO)) ==
1534 (SR_SEL | SR_IO)) {
1535 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
1536 NCR5380_reselect(instance);
1537 printk (KERN_ERR "scsi%d: reselection after won arbitration?\n",
1538 HOSTNO);
1539 NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
1540 return -1;
1541 }
1542#else
1543 while (time_before(jiffies, timeout) && !(NCR5380_read(STATUS_REG) & SR_BSY));
1544#endif
1545
1546
1547
1548
1549
1550
1551
1552 udelay(1);
1553
1554 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
1555
1556 if (!(NCR5380_read(STATUS_REG) & SR_BSY)) {
1557 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
1558 if (hostdata->targets_present & (1 << cmd->device->id)) {
1559 printk(KERN_ERR "scsi%d: weirdness\n", HOSTNO);
1560 if (hostdata->restart_select)
1561 printk(KERN_NOTICE "\trestart select\n");
1562 NCR_PRINT(NDEBUG_ANY);
1563 NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
1564 return -1;
1565 }
1566 cmd->result = DID_BAD_TARGET << 16;
1567#ifdef NCR5380_STATS
1568 collect_stats(hostdata, cmd);
1569#endif
1570#ifdef SUPPORT_TAGS
1571 cmd_free_tag( cmd );
1572#endif
1573 cmd->scsi_done(cmd);
1574 NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
1575 SEL_PRINTK("scsi%d: target did not respond within 250ms\n", HOSTNO);
1576 NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
1577 return 0;
1578 }
1579
1580 hostdata->targets_present |= (1 << cmd->device->id);
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598 while (!(NCR5380_read(STATUS_REG) & SR_REQ));
1599
1600 SEL_PRINTK("scsi%d: target %d selected, going into MESSAGE OUT phase.\n",
1601 HOSTNO, cmd->device->id);
1602 tmp[0] = IDENTIFY(1, cmd->device->lun);
1603
1604#ifdef SUPPORT_TAGS
1605 if (cmd->tag != TAG_NONE) {
1606 tmp[1] = hostdata->last_message = SIMPLE_QUEUE_TAG;
1607 tmp[2] = cmd->tag;
1608 len = 3;
1609 } else
1610 len = 1;
1611#else
1612 len = 1;
1613 cmd->tag=0;
1614#endif
1615
1616
1617 data = tmp;
1618 phase = PHASE_MSGOUT;
1619 NCR5380_transfer_pio(instance, &phase, &len, &data);
1620 SEL_PRINTK("scsi%d: nexus established.\n", HOSTNO);
1621
1622 hostdata->connected = cmd;
1623#ifndef SUPPORT_TAGS
1624 hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);
1625#endif
1626#ifdef SUN3_SCSI_VME
1627 dregs->csr |= CSR_INTR;
1628#endif
1629 initialize_SCp(cmd);
1630
1631
1632 return 0;
1633}
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660static int NCR5380_transfer_pio( struct Scsi_Host *instance,
1661 unsigned char *phase, int *count,
1662 unsigned char **data)
1663{
1664 register unsigned char p = *phase, tmp;
1665 register int c = *count;
1666 register unsigned char *d = *data;
1667
1668
1669
1670
1671
1672
1673
1674 NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(p));
1675
1676 do {
1677
1678
1679
1680
1681 while (!((tmp = NCR5380_read(STATUS_REG)) & SR_REQ));
1682
1683 HSH_PRINTK("scsi%d: REQ detected\n", HOSTNO);
1684
1685
1686 if ((tmp & PHASE_MASK) != p) {
1687 PIO_PRINTK("scsi%d: phase mismatch\n", HOSTNO);
1688 NCR_PRINT_PHASE(NDEBUG_PIO);
1689 break;
1690 }
1691
1692
1693 if (!(p & SR_IO))
1694 NCR5380_write(OUTPUT_DATA_REG, *d);
1695 else
1696 *d = NCR5380_read(CURRENT_SCSI_DATA_REG);
1697
1698 ++d;
1699
1700
1701
1702
1703
1704
1705
1706
1707 if (!(p & SR_IO)) {
1708 if (!((p & SR_MSG) && c > 1)) {
1709 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
1710 ICR_ASSERT_DATA);
1711 NCR_PRINT(NDEBUG_PIO);
1712 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
1713 ICR_ASSERT_DATA | ICR_ASSERT_ACK);
1714 } else {
1715 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
1716 ICR_ASSERT_DATA | ICR_ASSERT_ATN);
1717 NCR_PRINT(NDEBUG_PIO);
1718 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
1719 ICR_ASSERT_DATA | ICR_ASSERT_ATN | ICR_ASSERT_ACK);
1720 }
1721 } else {
1722 NCR_PRINT(NDEBUG_PIO);
1723 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ACK);
1724 }
1725
1726 while (NCR5380_read(STATUS_REG) & SR_REQ);
1727
1728 HSH_PRINTK("scsi%d: req false, handshake complete\n", HOSTNO);
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741 if (!(p == PHASE_MSGIN && c == 1)) {
1742 if (p == PHASE_MSGOUT && c > 1)
1743 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
1744 else
1745 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
1746 }
1747 } while (--c);
1748
1749 PIO_PRINTK("scsi%d: residual %d\n", HOSTNO, c);
1750
1751 *count = c;
1752 *data = d;
1753 tmp = NCR5380_read(STATUS_REG);
1754
1755
1756
1757 if ((tmp & SR_REQ) || (p == PHASE_MSGIN && c == 0))
1758 *phase = tmp & PHASE_MASK;
1759 else
1760 *phase = PHASE_UNKNOWN;
1761
1762 if (!c || (*phase == p))
1763 return 0;
1764 else
1765 return -1;
1766}
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777static int do_abort (struct Scsi_Host *host)
1778{
1779 unsigned char tmp, *msgptr, phase;
1780 int len;
1781
1782
1783 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795 while (!((tmp = NCR5380_read(STATUS_REG)) & SR_REQ));
1796
1797 NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp));
1798
1799 if ((tmp & PHASE_MASK) != PHASE_MSGOUT) {
1800 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN |
1801 ICR_ASSERT_ACK);
1802 while (NCR5380_read(STATUS_REG) & SR_REQ);
1803 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
1804 }
1805
1806 tmp = ABORT;
1807 msgptr = &tmp;
1808 len = 1;
1809 phase = PHASE_MSGOUT;
1810 NCR5380_transfer_pio (host, &phase, &len, &msgptr);
1811
1812
1813
1814
1815
1816
1817 return len ? -1 : 0;
1818}
1819
1820#if defined(REAL_DMA)
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841static int NCR5380_transfer_dma( struct Scsi_Host *instance,
1842 unsigned char *phase, int *count,
1843 unsigned char **data)
1844{
1845 SETUP_HOSTDATA(instance);
1846 register int c = *count;
1847 register unsigned char p = *phase;
1848 unsigned long flags;
1849
1850
1851 if(!sun3_dma_setup_done) {
1852 printk("scsi%d: transfer_dma without setup!\n", HOSTNO);
1853 BUG();
1854 }
1855 hostdata->dma_len = c;
1856
1857 DMA_PRINTK("scsi%d: initializing DMA for %s, %d bytes %s %p\n",
1858 HOSTNO, (p & SR_IO) ? "reading" : "writing",
1859 c, (p & SR_IO) ? "to" : "from", *data);
1860
1861
1862 local_irq_save(flags);
1863
1864
1865 sun3scsi_dma_start(c, *data);
1866
1867 if (p & SR_IO) {
1868 NCR5380_write(TARGET_COMMAND_REG, 1);
1869 NCR5380_read(RESET_PARITY_INTERRUPT_REG);
1870 NCR5380_write(INITIATOR_COMMAND_REG, 0);
1871 NCR5380_write(MODE_REG, (NCR5380_read(MODE_REG) | MR_DMA_MODE | MR_ENABLE_EOP_INTR));
1872 NCR5380_write(START_DMA_INITIATOR_RECEIVE_REG, 0);
1873 } else {
1874 NCR5380_write(TARGET_COMMAND_REG, 0);
1875 NCR5380_read(RESET_PARITY_INTERRUPT_REG);
1876 NCR5380_write(INITIATOR_COMMAND_REG, ICR_ASSERT_DATA);
1877 NCR5380_write(MODE_REG, (NCR5380_read(MODE_REG) | MR_DMA_MODE | MR_ENABLE_EOP_INTR));
1878 NCR5380_write(START_DMA_SEND_REG, 0);
1879 }
1880
1881#ifdef SUN3_SCSI_VME
1882 dregs->csr |= CSR_DMA_ENABLE;
1883#endif
1884
1885 local_irq_restore(flags);
1886
1887 sun3_dma_active = 1;
1888 return 0;
1889}
1890#endif
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909static void NCR5380_information_transfer (struct Scsi_Host *instance)
1910{
1911 SETUP_HOSTDATA(instance);
1912 unsigned long flags;
1913 unsigned char msgout = NOP;
1914 int sink = 0;
1915 int len;
1916#if defined(REAL_DMA)
1917 int transfersize;
1918#endif
1919 unsigned char *data;
1920 unsigned char phase, tmp, extended_msg[10], old_phase=0xff;
1921 struct scsi_cmnd *cmd = (struct scsi_cmnd *) hostdata->connected;
1922
1923#ifdef SUN3_SCSI_VME
1924 dregs->csr |= CSR_INTR;
1925#endif
1926
1927 while (1) {
1928 tmp = NCR5380_read(STATUS_REG);
1929
1930 if (tmp & SR_REQ) {
1931 phase = (tmp & PHASE_MASK);
1932 if (phase != old_phase) {
1933 old_phase = phase;
1934 NCR_PRINT_PHASE(NDEBUG_INFORMATION);
1935 }
1936
1937 if(phase == PHASE_CMDOUT) {
1938 void *d;
1939 unsigned long count;
1940
1941 if (!cmd->SCp.this_residual && cmd->SCp.buffers_residual) {
1942 count = cmd->SCp.buffer->length;
1943 d = SGADDR(cmd->SCp.buffer);
1944 } else {
1945 count = cmd->SCp.this_residual;
1946 d = cmd->SCp.ptr;
1947 }
1948#ifdef REAL_DMA
1949
1950 if((count > SUN3_DMA_MINSIZE) && (sun3_dma_setup_done
1951 != cmd))
1952 {
1953 if (cmd->request->cmd_type == REQ_TYPE_FS) {
1954 sun3scsi_dma_setup(d, count,
1955 rq_data_dir(cmd->request));
1956 sun3_dma_setup_done = cmd;
1957 }
1958 }
1959#endif
1960#ifdef SUN3_SCSI_VME
1961 dregs->csr |= CSR_INTR;
1962#endif
1963 }
1964
1965
1966 if (sink && (phase != PHASE_MSGOUT)) {
1967 NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp));
1968
1969 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN |
1970 ICR_ASSERT_ACK);
1971 while (NCR5380_read(STATUS_REG) & SR_REQ);
1972 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
1973 ICR_ASSERT_ATN);
1974 sink = 0;
1975 continue;
1976 }
1977
1978 switch (phase) {
1979 case PHASE_DATAOUT:
1980#if (NDEBUG & NDEBUG_NO_DATAOUT)
1981 printk("scsi%d: NDEBUG_NO_DATAOUT set, attempted DATAOUT "
1982 "aborted\n", HOSTNO);
1983 sink = 1;
1984 do_abort(instance);
1985 cmd->result = DID_ERROR << 16;
1986 cmd->scsi_done(cmd);
1987 return;
1988#endif
1989 case PHASE_DATAIN:
1990
1991
1992
1993
1994 if (!cmd->SCp.this_residual && cmd->SCp.buffers_residual) {
1995 ++cmd->SCp.buffer;
1996 --cmd->SCp.buffers_residual;
1997 cmd->SCp.this_residual = cmd->SCp.buffer->length;
1998 cmd->SCp.ptr = SGADDR(cmd->SCp.buffer);
1999 INF_PRINTK("scsi%d: %d bytes and %d buffers left\n",
2000 HOSTNO, cmd->SCp.this_residual,
2001 cmd->SCp.buffers_residual);
2002 }
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019#if defined(REAL_DMA)
2020
2021 if((transfersize =
2022 NCR5380_dma_xfer_len(instance,cmd,phase)) > SUN3_DMA_MINSIZE) {
2023 len = transfersize;
2024 cmd->SCp.phase = phase;
2025
2026 if (NCR5380_transfer_dma(instance, &phase,
2027 &len, (unsigned char **) &cmd->SCp.ptr)) {
2028
2029
2030
2031
2032 printk(KERN_NOTICE "scsi%d: switching target %d "
2033 "lun %d to slow handshake\n", HOSTNO,
2034 cmd->device->id, cmd->device->lun);
2035 cmd->device->borken = 1;
2036 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
2037 ICR_ASSERT_ATN);
2038 sink = 1;
2039 do_abort(instance);
2040 cmd->result = DID_ERROR << 16;
2041 cmd->scsi_done(cmd);
2042
2043 } else {
2044#ifdef REAL_DMA
2045
2046
2047
2048
2049
2050 return;
2051#else
2052 cmd->SCp.this_residual -= transfersize - len;
2053#endif
2054 }
2055 } else
2056#endif
2057 NCR5380_transfer_pio(instance, &phase,
2058 (int *) &cmd->SCp.this_residual, (unsigned char **)
2059 &cmd->SCp.ptr);
2060#ifdef REAL_DMA
2061
2062 if(sun3_dma_setup_done == cmd)
2063 sun3_dma_setup_done = NULL;
2064#endif
2065
2066 break;
2067 case PHASE_MSGIN:
2068 len = 1;
2069 data = &tmp;
2070 NCR5380_write(SELECT_ENABLE_REG, 0);
2071 NCR5380_transfer_pio(instance, &phase, &len, &data);
2072 cmd->SCp.Message = tmp;
2073
2074 switch (tmp) {
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085#ifdef LINKED
2086 case LINKED_CMD_COMPLETE:
2087 case LINKED_FLG_CMD_COMPLETE:
2088
2089 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
2090
2091 LNK_PRINTK("scsi%d: target %d lun %d linked command "
2092 "complete.\n", HOSTNO, cmd->device->id, cmd->device->lun);
2093
2094
2095 NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
2096
2097
2098
2099
2100
2101
2102 if (!cmd->next_link) {
2103 printk(KERN_NOTICE "scsi%d: target %d lun %d "
2104 "linked command complete, no next_link\n",
2105 HOSTNO, cmd->device->id, cmd->device->lun);
2106 sink = 1;
2107 do_abort (instance);
2108 return;
2109 }
2110
2111 initialize_SCp(cmd->next_link);
2112
2113
2114 cmd->next_link->tag = cmd->tag;
2115 cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8);
2116 LNK_PRINTK("scsi%d: target %d lun %d linked request "
2117 "done, calling scsi_done().\n",
2118 HOSTNO, cmd->device->id, cmd->device->lun);
2119#ifdef NCR5380_STATS
2120 collect_stats(hostdata, cmd);
2121#endif
2122 cmd->scsi_done(cmd);
2123 cmd = hostdata->connected;
2124 break;
2125#endif
2126 case ABORT:
2127 case COMMAND_COMPLETE:
2128
2129 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
2130 hostdata->connected = NULL;
2131 QU_PRINTK("scsi%d: command for target %d, lun %d "
2132 "completed\n", HOSTNO, cmd->device->id, cmd->device->lun);
2133#ifdef SUPPORT_TAGS
2134 cmd_free_tag( cmd );
2135 if (status_byte(cmd->SCp.Status) == QUEUE_FULL) {
2136
2137
2138
2139
2140
2141
2142
2143
2144 TAG_ALLOC *ta = &TagAlloc[cmd->device->id][cmd->device->lun];
2145 TAG_PRINTK("scsi%d: target %d lun %d returned "
2146 "QUEUE_FULL after %d commands\n",
2147 HOSTNO, cmd->device->id, cmd->device->lun,
2148 ta->nr_allocated);
2149 if (ta->queue_size > ta->nr_allocated)
2150 ta->nr_allocated = ta->queue_size;
2151 }
2152#else
2153 hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
2154#endif
2155
2156 NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174 if (cmd->cmnd[0] != REQUEST_SENSE)
2175 cmd->result = cmd->SCp.Status | (cmd->SCp.Message << 8);
2176 else if (status_byte(cmd->SCp.Status) != GOOD)
2177 cmd->result = (cmd->result & 0x00ffff) | (DID_ERROR << 16);
2178
2179#ifdef AUTOSENSE
2180 if ((cmd->cmnd[0] == REQUEST_SENSE) &&
2181 hostdata->ses.cmd_len) {
2182 scsi_eh_restore_cmnd(cmd, &hostdata->ses);
2183 hostdata->ses.cmd_len = 0 ;
2184 }
2185
2186 if ((cmd->cmnd[0] != REQUEST_SENSE) &&
2187 (status_byte(cmd->SCp.Status) == CHECK_CONDITION)) {
2188 scsi_eh_prep_cmnd(cmd, &hostdata->ses, NULL, 0, ~0);
2189 ASEN_PRINTK("scsi%d: performing request sense\n",
2190 HOSTNO);
2191
2192
2193
2194
2195
2196 local_irq_save(flags);
2197 LIST(cmd,hostdata->issue_queue);
2198 SET_NEXT(cmd, hostdata->issue_queue);
2199 hostdata->issue_queue = (struct scsi_cmnd *) cmd;
2200 local_irq_restore(flags);
2201 QU_PRINTK("scsi%d: REQUEST SENSE added to head of "
2202 "issue queue\n", H_NO(cmd));
2203 } else
2204#endif
2205 {
2206#ifdef NCR5380_STATS
2207 collect_stats(hostdata, cmd);
2208#endif
2209 cmd->scsi_done(cmd);
2210 }
2211
2212 NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
2213
2214
2215
2216
2217 NCR5380_write(TARGET_COMMAND_REG, 0);
2218
2219 while ((NCR5380_read(STATUS_REG) & SR_BSY) && !hostdata->connected)
2220 barrier();
2221
2222 return;
2223 case MESSAGE_REJECT:
2224
2225 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
2226
2227 NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
2228 switch (hostdata->last_message) {
2229 case HEAD_OF_QUEUE_TAG:
2230 case ORDERED_QUEUE_TAG:
2231 case SIMPLE_QUEUE_TAG:
2232
2233
2234
2235
2236
2237
2238 cmd->device->tagged_supported = 0;
2239 hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun);
2240 cmd->tag = TAG_NONE;
2241 TAG_PRINTK("scsi%d: target %d lun %d rejected "
2242 "QUEUE_TAG message; tagged queuing "
2243 "disabled\n",
2244 HOSTNO, cmd->device->id, cmd->device->lun);
2245 break;
2246 }
2247 break;
2248 case DISCONNECT:
2249
2250 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
2251 local_irq_save(flags);
2252 cmd->device->disconnect = 1;
2253 LIST(cmd,hostdata->disconnected_queue);
2254 SET_NEXT(cmd, hostdata->disconnected_queue);
2255 hostdata->connected = NULL;
2256 hostdata->disconnected_queue = cmd;
2257 local_irq_restore(flags);
2258 QU_PRINTK("scsi%d: command for target %d lun %d was "
2259 "moved from connected to the "
2260 "disconnected_queue\n", HOSTNO,
2261 cmd->device->id, cmd->device->lun);
2262
2263
2264
2265
2266 NCR5380_write(TARGET_COMMAND_REG, 0);
2267
2268
2269 NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
2270
2271 while ((NCR5380_read(STATUS_REG) & SR_BSY) && !hostdata->connected)
2272 barrier();
2273#ifdef SUN3_SCSI_VME
2274 dregs->csr |= CSR_DMA_ENABLE;
2275#endif
2276 return;
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287 case SAVE_POINTERS:
2288 case RESTORE_POINTERS:
2289
2290 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
2291
2292 NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
2293 break;
2294 case EXTENDED_MESSAGE:
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307 extended_msg[0] = EXTENDED_MESSAGE;
2308
2309 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
2310
2311 EXT_PRINTK("scsi%d: receiving extended message\n", HOSTNO);
2312
2313 len = 2;
2314 data = extended_msg + 1;
2315 phase = PHASE_MSGIN;
2316 NCR5380_transfer_pio(instance, &phase, &len, &data);
2317 EXT_PRINTK("scsi%d: length=%d, code=0x%02x\n", HOSTNO,
2318 (int)extended_msg[1], (int)extended_msg[2]);
2319
2320 if (!len && extended_msg[1] <=
2321 (sizeof (extended_msg) - 1)) {
2322
2323 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
2324 len = extended_msg[1] - 1;
2325 data = extended_msg + 3;
2326 phase = PHASE_MSGIN;
2327
2328 NCR5380_transfer_pio(instance, &phase, &len, &data);
2329 EXT_PRINTK("scsi%d: message received, residual %d\n",
2330 HOSTNO, len);
2331
2332 switch (extended_msg[2]) {
2333 case EXTENDED_SDTR:
2334 case EXTENDED_WDTR:
2335 case EXTENDED_MODIFY_DATA_POINTER:
2336 case EXTENDED_EXTENDED_IDENTIFY:
2337 tmp = 0;
2338 }
2339 } else if (len) {
2340 printk(KERN_NOTICE "scsi%d: error receiving "
2341 "extended message\n", HOSTNO);
2342 tmp = 0;
2343 } else {
2344 printk(KERN_NOTICE "scsi%d: extended message "
2345 "code %02x length %d is too long\n",
2346 HOSTNO, extended_msg[2], extended_msg[1]);
2347 tmp = 0;
2348 }
2349
2350
2351
2352
2353
2354
2355 default:
2356 if (!tmp) {
2357 printk(KERN_DEBUG "scsi%d: rejecting message ", HOSTNO);
2358 spi_print_msg(extended_msg);
2359 printk("\n");
2360 } else if (tmp != EXTENDED_MESSAGE)
2361 printk(KERN_DEBUG "scsi%d: rejecting unknown "
2362 "message %02x from target %d, lun %d\n",
2363 HOSTNO, tmp, cmd->device->id, cmd->device->lun);
2364 else
2365 printk(KERN_DEBUG "scsi%d: rejecting unknown "
2366 "extended message "
2367 "code %02x, length %d from target %d, lun %d\n",
2368 HOSTNO, extended_msg[1], extended_msg[0],
2369 cmd->device->id, cmd->device->lun);
2370
2371
2372 msgout = MESSAGE_REJECT;
2373 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE |
2374 ICR_ASSERT_ATN);
2375 break;
2376 }
2377 break;
2378 case PHASE_MSGOUT:
2379 len = 1;
2380 data = &msgout;
2381 hostdata->last_message = msgout;
2382 NCR5380_transfer_pio(instance, &phase, &len, &data);
2383 if (msgout == ABORT) {
2384#ifdef SUPPORT_TAGS
2385 cmd_free_tag( cmd );
2386#else
2387 hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
2388#endif
2389 hostdata->connected = NULL;
2390 cmd->result = DID_ERROR << 16;
2391#ifdef NCR5380_STATS
2392 collect_stats(hostdata, cmd);
2393#endif
2394 cmd->scsi_done(cmd);
2395 NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
2396 return;
2397 }
2398 msgout = NOP;
2399 break;
2400 case PHASE_CMDOUT:
2401 len = cmd->cmd_len;
2402 data = cmd->cmnd;
2403
2404
2405
2406
2407
2408 NCR5380_transfer_pio(instance, &phase, &len,
2409 &data);
2410 break;
2411 case PHASE_STATIN:
2412 len = 1;
2413 data = &tmp;
2414 NCR5380_transfer_pio(instance, &phase, &len, &data);
2415 cmd->SCp.Status = tmp;
2416 break;
2417 default:
2418 printk("scsi%d: unknown phase\n", HOSTNO);
2419 NCR_PRINT(NDEBUG_ANY);
2420 }
2421 }
2422 }
2423}
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439static void NCR5380_reselect (struct Scsi_Host *instance)
2440{
2441 SETUP_HOSTDATA(instance);
2442 unsigned char target_mask;
2443 unsigned char lun;
2444#ifdef SUPPORT_TAGS
2445 unsigned char tag;
2446#endif
2447 unsigned char msg[3];
2448 struct scsi_cmnd *tmp = NULL, *prev;
2449
2450
2451
2452
2453
2454
2455
2456 NCR5380_write(MODE_REG, MR_BASE);
2457 hostdata->restart_select = 1;
2458
2459 target_mask = NCR5380_read(CURRENT_SCSI_DATA_REG) & ~(hostdata->id_mask);
2460
2461 RSL_PRINTK("scsi%d: reselect\n", HOSTNO);
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_BSY);
2473
2474 while (NCR5380_read(STATUS_REG) & SR_SEL);
2475 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
2476
2477
2478
2479
2480
2481 while (!(NCR5380_read(STATUS_REG) & SR_REQ));
2482
2483#if 1
2484
2485 NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(PHASE_MSGIN));
2486
2487
2488 msg[0] = NCR5380_read(CURRENT_SCSI_DATA_REG);
2489#endif
2490
2491 if (!(msg[0] & 0x80)) {
2492 printk(KERN_DEBUG "scsi%d: expecting IDENTIFY message, got ", HOSTNO);
2493 spi_print_msg(msg);
2494 do_abort(instance);
2495 return;
2496 }
2497 lun = (msg[0] & 0x07);
2498
2499
2500
2501
2502
2503
2504 for (tmp = (struct scsi_cmnd *) hostdata->disconnected_queue, prev = NULL;
2505 tmp; prev = tmp, tmp = NEXT(tmp) ) {
2506 if ((target_mask == (1 << tmp->device->id)) && (lun == tmp->device->lun)
2507#ifdef SUPPORT_TAGS
2508 && (tag == tmp->tag)
2509#endif
2510 ) {
2511 if (prev) {
2512 REMOVE(prev, NEXT(prev), tmp, NEXT(tmp));
2513 SET_NEXT(prev, NEXT(tmp));
2514 } else {
2515 REMOVE(-1, hostdata->disconnected_queue, tmp, NEXT(tmp));
2516 hostdata->disconnected_queue = NEXT(tmp);
2517 }
2518 SET_NEXT(tmp, NULL);
2519 break;
2520 }
2521 }
2522
2523 if (!tmp) {
2524 printk(KERN_WARNING "scsi%d: warning: target bitmask %02x lun %d "
2525#ifdef SUPPORT_TAGS
2526 "tag %d "
2527#endif
2528 "not in disconnected_queue.\n",
2529 HOSTNO, target_mask, lun
2530#ifdef SUPPORT_TAGS
2531 , tag
2532#endif
2533 );
2534
2535
2536
2537
2538 do_abort(instance);
2539 return;
2540 }
2541#if 1
2542
2543 {
2544 void *d;
2545 unsigned long count;
2546
2547 if (!tmp->SCp.this_residual && tmp->SCp.buffers_residual) {
2548 count = tmp->SCp.buffer->length;
2549 d = SGADDR(tmp->SCp.buffer);
2550 } else {
2551 count = tmp->SCp.this_residual;
2552 d = tmp->SCp.ptr;
2553 }
2554#ifdef REAL_DMA
2555
2556 if((count > SUN3_DMA_MINSIZE) && (sun3_dma_setup_done != tmp))
2557 {
2558 sun3scsi_dma_setup(d, count, rq_data_dir(tmp->request));
2559 sun3_dma_setup_done = tmp;
2560 }
2561#endif
2562 }
2563#endif
2564
2565 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ACK);
2566
2567 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
2568
2569#ifdef SUPPORT_TAGS
2570
2571
2572
2573
2574 tag = TAG_NONE;
2575 if (phase == PHASE_MSGIN && setup_use_tagged_queuing) {
2576
2577 NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE );
2578 len = 2;
2579 data = msg+1;
2580 if (!NCR5380_transfer_pio(instance, &phase, &len, &data) &&
2581 msg[1] == SIMPLE_QUEUE_TAG)
2582 tag = msg[2];
2583 TAG_PRINTK("scsi%d: target mask %02x, lun %d sent tag %d at "
2584 "reselection\n", HOSTNO, target_mask, lun, tag);
2585 }
2586#endif
2587
2588 hostdata->connected = tmp;
2589 RSL_PRINTK("scsi%d: nexus established, target = %d, lun = %d, tag = %d\n",
2590 HOSTNO, tmp->target, tmp->lun, tmp->tag);
2591}
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611static int NCR5380_abort(struct scsi_cmnd *cmd)
2612{
2613 struct Scsi_Host *instance = cmd->device->host;
2614 SETUP_HOSTDATA(instance);
2615 struct scsi_cmnd *tmp, **prev;
2616 unsigned long flags;
2617
2618 scmd_printk(KERN_NOTICE, cmd, "aborting command\n");
2619
2620 NCR5380_print_status (instance);
2621
2622 local_irq_save(flags);
2623
2624 ABRT_PRINTK("scsi%d: abort called basr 0x%02x, sr 0x%02x\n", HOSTNO,
2625 NCR5380_read(BUS_AND_STATUS_REG),
2626 NCR5380_read(STATUS_REG));
2627
2628#if 1
2629
2630
2631
2632
2633
2634
2635 if (hostdata->connected == cmd) {
2636
2637 ABRT_PRINTK("scsi%d: aborting connected command\n", HOSTNO);
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655 if (do_abort(instance) == 0) {
2656 hostdata->aborted = 1;
2657 hostdata->connected = NULL;
2658 cmd->result = DID_ABORT << 16;
2659#ifdef SUPPORT_TAGS
2660 cmd_free_tag( cmd );
2661#else
2662 hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
2663#endif
2664 local_irq_restore(flags);
2665 cmd->scsi_done(cmd);
2666 return SCSI_ABORT_SUCCESS;
2667 } else {
2668
2669 printk("scsi%d: abort of connected command failed!\n", HOSTNO);
2670 return SCSI_ABORT_ERROR;
2671 }
2672 }
2673#endif
2674
2675
2676
2677
2678
2679 for (prev = (struct scsi_cmnd **) &(hostdata->issue_queue),
2680 tmp = (struct scsi_cmnd *) hostdata->issue_queue;
2681 tmp; prev = NEXTADDR(tmp), tmp = NEXT(tmp))
2682 if (cmd == tmp) {
2683 REMOVE(5, *prev, tmp, NEXT(tmp));
2684 (*prev) = NEXT(tmp);
2685 SET_NEXT(tmp, NULL);
2686 tmp->result = DID_ABORT << 16;
2687 local_irq_restore(flags);
2688 ABRT_PRINTK("scsi%d: abort removed command from issue queue.\n",
2689 HOSTNO);
2690
2691
2692 tmp->scsi_done(tmp);
2693 return SCSI_ABORT_SUCCESS;
2694 }
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707 if (hostdata->connected) {
2708 local_irq_restore(flags);
2709 ABRT_PRINTK("scsi%d: abort failed, command connected.\n", HOSTNO);
2710 return SCSI_ABORT_SNOOZE;
2711 }
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738 for (tmp = (struct scsi_cmnd *) hostdata->disconnected_queue; tmp;
2739 tmp = NEXT(tmp))
2740 if (cmd == tmp) {
2741 local_irq_restore(flags);
2742 ABRT_PRINTK("scsi%d: aborting disconnected command.\n", HOSTNO);
2743
2744 if (NCR5380_select (instance, cmd, (int) cmd->tag))
2745 return SCSI_ABORT_BUSY;
2746
2747 ABRT_PRINTK("scsi%d: nexus reestablished.\n", HOSTNO);
2748
2749 do_abort (instance);
2750
2751 local_irq_save(flags);
2752 for (prev = (struct scsi_cmnd **) &(hostdata->disconnected_queue),
2753 tmp = (struct scsi_cmnd *) hostdata->disconnected_queue;
2754 tmp; prev = NEXTADDR(tmp), tmp = NEXT(tmp) )
2755 if (cmd == tmp) {
2756 REMOVE(5, *prev, tmp, NEXT(tmp));
2757 *prev = NEXT(tmp);
2758 SET_NEXT(tmp, NULL);
2759 tmp->result = DID_ABORT << 16;
2760
2761
2762
2763
2764#ifdef SUPPORT_TAGS
2765 cmd_free_tag( tmp );
2766#else
2767 hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
2768#endif
2769 local_irq_restore(flags);
2770 tmp->scsi_done(tmp);
2771 return SCSI_ABORT_SUCCESS;
2772 }
2773 }
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785 local_irq_restore(flags);
2786 printk(KERN_INFO "scsi%d: warning : SCSI command probably completed successfully before abortion\n", HOSTNO);
2787
2788 return SCSI_ABORT_NOT_RUNNING;
2789}
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801static int NCR5380_bus_reset(struct scsi_cmnd *cmd)
2802{
2803 SETUP_HOSTDATA(cmd->device->host);
2804 int i;
2805 unsigned long flags;
2806#if 1
2807 struct scsi_cmnd *connected, *disconnected_queue;
2808#endif
2809
2810
2811 NCR5380_print_status (cmd->device->host);
2812
2813
2814 NCR5380_write( TARGET_COMMAND_REG,
2815 PHASE_SR_TO_TCR( NCR5380_read(STATUS_REG) ));
2816
2817 NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST );
2818 udelay (40);
2819
2820 NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE );
2821 NCR5380_write( MODE_REG, MR_BASE );
2822 NCR5380_write( TARGET_COMMAND_REG, 0 );
2823 NCR5380_write( SELECT_ENABLE_REG, 0 );
2824
2825
2826 (void)NCR5380_read( RESET_PARITY_INTERRUPT_REG );
2827
2828#if 1
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838 local_irq_save(flags);
2839 connected = (struct scsi_cmnd *)hostdata->connected;
2840 hostdata->connected = NULL;
2841 disconnected_queue = (struct scsi_cmnd *)hostdata->disconnected_queue;
2842 hostdata->disconnected_queue = NULL;
2843#ifdef SUPPORT_TAGS
2844 free_all_tags();
2845#endif
2846 for( i = 0; i < 8; ++i )
2847 hostdata->busy[i] = 0;
2848#ifdef REAL_DMA
2849 hostdata->dma_len = 0;
2850#endif
2851 local_irq_restore(flags);
2852
2853
2854
2855
2856
2857
2858 if ((cmd = connected)) {
2859 ABRT_PRINTK("scsi%d: reset aborted a connected command\n", H_NO(cmd));
2860 cmd->result = (cmd->result & 0xffff) | (DID_RESET << 16);
2861 cmd->scsi_done( cmd );
2862 }
2863
2864 for (i = 0; (cmd = disconnected_queue); ++i) {
2865 disconnected_queue = NEXT(cmd);
2866 SET_NEXT(cmd, NULL);
2867 cmd->result = (cmd->result & 0xffff) | (DID_RESET << 16);
2868 cmd->scsi_done( cmd );
2869 }
2870 if (i > 0)
2871 ABRT_PRINTK("scsi: reset aborted %d disconnected command(s)\n", i);
2872
2873
2874
2875
2876
2877
2878 return SCSI_RESET_SUCCESS | SCSI_RESET_BUS_RESET;
2879#else
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904 if (hostdata->issue_queue)
2905 ABRT_PRINTK("scsi%d: reset aborted issued command(s)\n", H_NO(cmd));
2906 if (hostdata->connected)
2907 ABRT_PRINTK("scsi%d: reset aborted a connected command\n", H_NO(cmd));
2908 if (hostdata->disconnected_queue)
2909 ABRT_PRINTK("scsi%d: reset aborted disconnected command(s)\n", H_NO(cmd));
2910
2911 local_irq_save(flags);
2912 hostdata->issue_queue = NULL;
2913 hostdata->connected = NULL;
2914 hostdata->disconnected_queue = NULL;
2915#ifdef SUPPORT_TAGS
2916 free_all_tags();
2917#endif
2918 for( i = 0; i < 8; ++i )
2919 hostdata->busy[i] = 0;
2920#ifdef REAL_DMA
2921 hostdata->dma_len = 0;
2922#endif
2923 local_irq_restore(flags);
2924
2925
2926 return SCSI_RESET_WAKEUP | SCSI_RESET_BUS_RESET;
2927#endif
2928}
2929
2930
2931
2932
2933