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