This source file includes following definitions.
- find_and_clear_bit_16
- xchgb
- outl
- log_ultrastor_abort
- ultrastor_14f_detect
- ARRAY_SIZE
- request_irq
- request_dma
- ultrastor_24f_detect
- ultrastor_detect
- ultrastor_info
- build_sg_list
- ultrastor_queuecommand
- ultrastor_abort
- ultrastor_reset
- ultrastor_biosparam
- ultrastor_interrupt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117 #include <linux/stddef.h>
118 #include <linux/string.h>
119 #include <linux/sched.h>
120 #include <linux/kernel.h>
121 #include <linux/ioport.h>
122
123 #include <asm/io.h>
124 #include <asm/bitops.h>
125 #include <asm/system.h>
126 #include <asm/dma.h>
127
128 #define ULTRASTOR_PRIVATE
129 #include "../block/blk.h"
130 #include "scsi.h"
131 #include "hosts.h"
132 #include "ultrastor.h"
133
134 #define FALSE 0
135 #define TRUE 1
136
137 #ifndef ULTRASTOR_DEBUG
138 #define ULTRASTOR_DEBUG (UD_ABORT|UD_CSIR|UD_RESET)
139 #endif
140
141 #define VERSION "1.11 alpha"
142
143 #define ARRAY_SIZE(arr) (sizeof (arr) / sizeof (arr)[0])
144
145 #define PACKED __attribute__((packed))
146 #define ALIGNED(x) __attribute__((aligned(x)))
147
148
149
150
151
152
153
154 typedef struct {
155 unsigned int address;
156 unsigned int num_bytes;
157 } ultrastor_sg_list;
158
159
160
161
162 struct mscp {
163 unsigned char opcode: 3;
164 unsigned char xdir: 2;
165 unsigned char dcn: 1;
166 unsigned char ca: 1;
167 unsigned char sg: 1;
168 unsigned char target_id: 3;
169 unsigned char ch_no: 2;
170 unsigned char lun: 3;
171 unsigned int transfer_data PACKED;
172 unsigned int transfer_data_length PACKED;
173 unsigned int command_link PACKED;
174 unsigned char scsi_command_link_id;
175 unsigned char number_of_sg_list;
176 unsigned char length_of_sense_byte;
177 unsigned char length_of_scsi_cdbs;
178 unsigned char scsi_cdbs[12];
179 unsigned char adapter_status;
180 unsigned char target_status;
181 unsigned int sense_data PACKED;
182
183
184 void (*done)(Scsi_Cmnd *);
185 Scsi_Cmnd *SCint;
186 ultrastor_sg_list sglist[ULTRASTOR_14F_MAX_SG];
187 };
188
189
190
191 #define U14F_PRODUCT_ID(port) ((port) + 0x4)
192 #define CONFIG(port) ((port) + 0x6)
193
194
195 #define LCL_DOORBELL_MASK(port) ((port) + 0x0)
196 #define LCL_DOORBELL_INTR(port) ((port) + 0x1)
197 #define SYS_DOORBELL_MASK(port) ((port) + 0x2)
198 #define SYS_DOORBELL_INTR(port) ((port) + 0x3)
199
200
201
202
203
204
205
206
207
208
209
210 static struct ultrastor_config
211 {
212 unsigned short port_address;
213 unsigned short doorbell_address;
214 unsigned short ogm_address;
215 unsigned short icm_address;
216 const void *bios_segment;
217 unsigned char interrupt: 4;
218 unsigned char dma_channel: 3;
219 unsigned char bios_drive_number: 1;
220 unsigned char heads;
221 unsigned char sectors;
222 unsigned char ha_scsi_id: 3;
223 unsigned char subversion: 4;
224 unsigned char revision;
225
226
227 unsigned char slot;
228
229 #ifdef PRINT_U24F_VERSION
230 volatile int csir_done;
231 #endif
232
233
234 int host_number;
235
236
237
238
239
240 #if ULTRASTOR_MAX_CMDS == 1
241 unsigned char mscp_busy;
242 #else
243 unsigned short mscp_free;
244 #endif
245 volatile unsigned char aborted[ULTRASTOR_MAX_CMDS];
246 struct mscp mscp[ULTRASTOR_MAX_CMDS];
247 } config = {0};
248
249
250 int ultrastor_bus_reset = 0;
251
252
253
254 static const void *const bios_segment_table[8] = {
255 NULL, (void *)0xC4000, (void *)0xC8000, (void *)0xCC000,
256 (void *)0xD0000, (void *)0xD4000, (void *)0xD8000, (void *)0xDC000,
257 };
258
259
260 static const unsigned char interrupt_table_14f[4] = { 15, 14, 11, 10 };
261
262
263 static const unsigned char dma_channel_table_14f[4] = { 5, 6, 7, 0 };
264
265
266 static const struct {
267 unsigned char heads;
268 unsigned char sectors;
269 } mapping_table[4] = { { 16, 63 }, { 64, 32 }, { 64, 63 }, { 64, 32 } };
270
271 #ifndef PORT_OVERRIDE
272
273 static const unsigned short ultrastor_ports_14f[] = {
274 0x330, 0x340, 0x230, 0x240, 0x210, 0x130, 0x140,
275 };
276 #endif
277
278 static void ultrastor_interrupt(int cpl);
279 static inline void build_sg_list(struct mscp *, Scsi_Cmnd *SCpnt);
280
281
282 static inline int find_and_clear_bit_16(unsigned short *field)
283 {
284 int rv;
285 cli();
286 if (*field == 0) panic("No free mscp");
287 asm("xorl %0,%0\n0:\tbsfw %1,%w0\n\tbtr %0,%1\n\tjnc 0b"
288 : "=&r" (rv), "=m" (*field) : "1" (*field));
289 sti();
290 return rv;
291 }
292
293
294
295
296 static inline unsigned char xchgb(unsigned char reg,
297 volatile unsigned char *mem)
298 {
299 asm("xchgb %0,%1" :
300 "=r" (reg), "=m" (*(unsigned char *)mem) :
301 "0" (reg), "1" (*(unsigned char *)mem));
302 return reg;
303 }
304
305 static inline void outl(unsigned int value, unsigned short port)
306 {
307 __asm__ __volatile__ ("outl %%al,%%dx"
308 : :"a" (value),"d" ((unsigned short) port));
309 }
310
311 static inline unsigned int inl(unsigned short port)
312 {
313 unsigned int _v;
314 __asm__ __volatile__ ("inl %%dx,%%eax"
315 :"=a" (_v):"d" ((unsigned short) port),"0" (0));
316 return _v;
317 }
318
319 #if ULTRASTOR_DEBUG & (UD_COMMAND | UD_ABORT)
320
321 static void log_ultrastor_abort(register struct ultrastor_config *config,
322 int command)
323 {
324 static char fmt[80] = "abort %d (%x); MSCP free pool: %x;";
325 register int i;
326 int flags;
327 save_flags(flags);
328 cli();
329
330 for (i = 0; i < ULTRASTOR_MAX_CMDS; i++)
331 {
332 fmt[20 + i*2] = ' ';
333 if (! (config->mscp_free & (1 << i)))
334 fmt[21 + i*2] = '0' + config->mscp[i].target_id;
335 else
336 fmt[21 + i*2] = '-';
337 }
338 fmt[20 + ULTRASTOR_MAX_CMDS * 2] = '\n';
339 fmt[21 + ULTRASTOR_MAX_CMDS * 2] = 0;
340 printk(fmt, command, &config->mscp[command], config->mscp_free);
341 restore_flags(flags);
342 }
343 #endif
344
345 static int ultrastor_14f_detect(int hostnum)
346 {
347 size_t i;
348 unsigned char in_byte, version_byte = 0;
349 struct config_1 {
350 unsigned char bios_segment: 3;
351 unsigned char removable_disks_as_fixed: 1;
352 unsigned char interrupt: 2;
353 unsigned char dma_channel: 2;
354 } config_1;
355 struct config_2 {
356 unsigned char ha_scsi_id: 3;
357 unsigned char mapping_mode: 2;
358 unsigned char bios_drive_number: 1;
359 unsigned char tfr_port: 2;
360 } config_2;
361
362 #if (ULTRASTOR_DEBUG & UD_DETECT)
363 printk("US14F: detect: called\n");
364 #endif
365
366
367 if (config.bios_segment)
368 return FALSE;
369
370 #ifdef PORT_OVERRIDE
371 if(check_region(PORT_OVERRIDE, 0xc)) {
372 printk("Ultrastor I/O space already in use\n");
373 return FALSE;
374 };
375 config.port_address = PORT_OVERRIDE;
376 #else
377 for (i = 0; i < ARRAY_SIZE(ultrastor_ports_14f); i++) {
378 if(check_region(ultrastor_ports_14f[i], 0x0c)) continue;
379 config.port_address = ultrastor_ports_14f[i];
380 #endif
381
382 #if (ULTRASTOR_DEBUG & UD_DETECT)
383 printk("US14F: detect: testing port address %03X\n", config.port_address);
384 #endif
385
386 in_byte = inb(U14F_PRODUCT_ID(config.port_address));
387 if (in_byte != US14F_PRODUCT_ID_0) {
388 #if (ULTRASTOR_DEBUG & UD_DETECT)
389 # ifdef PORT_OVERRIDE
390 printk("US14F: detect: wrong product ID 0 - %02X\n", in_byte);
391 # else
392 printk("US14F: detect: no adapter at port %03X\n", config.port_address);
393 # endif
394 #endif
395 #ifdef PORT_OVERRIDE
396 return FALSE;
397 #else
398 continue;
399 #endif
400 }
401 in_byte = inb(U14F_PRODUCT_ID(config.port_address) + 1);
402
403 if ((in_byte & 0xF0) != US14F_PRODUCT_ID_1) {
404 #if (ULTRASTOR_DEBUG & UD_DETECT)
405 # ifdef PORT_OVERRIDE
406 printk("US14F: detect: wrong product ID 1 - %02X\n", in_byte);
407 # else
408 printk("US14F: detect: no adapter at port %03X\n", config.port_address);
409 # endif
410 #endif
411 #ifdef PORT_OVERRIDE
412 return FALSE;
413 #else
414 continue;
415 #endif
416 }
417 version_byte = in_byte;
418 #ifndef PORT_OVERRIDE
419 break;
420 }
421 if (i == ARRAY_SIZE(ultrastor_ports_14f)) {
422 # if (ULTRASTOR_DEBUG & UD_DETECT)
423 printk("US14F: detect: no port address found!\n");
424 # endif
425 return FALSE;
426 }
427 #endif
428
429 #if (ULTRASTOR_DEBUG & UD_DETECT)
430 printk("US14F: detect: adapter found at port address %03X\n",
431 config.port_address);
432 #endif
433
434
435
436 outb(ultrastor_bus_reset ? 0xc2 : 0x82, LCL_DOORBELL_MASK(config.port_address));
437
438
439
440
441 snarf_region(config.port_address, 0x0c);
442
443 *(char *)&config_1 = inb(CONFIG(config.port_address + 0));
444 *(char *)&config_2 = inb(CONFIG(config.port_address + 1));
445 config.bios_segment = bios_segment_table[config_1.bios_segment];
446 config.doorbell_address = config.port_address;
447 config.ogm_address = config.port_address + 0x8;
448 config.icm_address = config.port_address + 0xC;
449 config.interrupt = interrupt_table_14f[config_1.interrupt];
450 config.ha_scsi_id = config_2.ha_scsi_id;
451 config.heads = mapping_table[config_2.mapping_mode].heads;
452 config.sectors = mapping_table[config_2.mapping_mode].sectors;
453 config.bios_drive_number = config_2.bios_drive_number;
454 config.subversion = (version_byte & 0x0F);
455 if (config.subversion == U34F)
456 config.dma_channel = 0;
457 else
458 config.dma_channel = dma_channel_table_14f[config_1.dma_channel];
459
460 if (!config.bios_segment) {
461 #if (ULTRASTOR_DEBUG & UD_DETECT)
462 printk("US14F: detect: not detected.\n");
463 #endif
464 return FALSE;
465 }
466
467
468 if (config.subversion != U34F)
469 if (!config.dma_channel || !(config_2.tfr_port & 0x2)) {
470 #if (ULTRASTOR_DEBUG & UD_DETECT)
471 printk("US14F: detect: consistancy check failed\n");
472 #endif
473 return FALSE;
474 }
475
476
477
478
479
480
481 #if (ULTRASTOR_DEBUG & UD_DETECT)
482 printk("US14F: detect: detect succeeded\n"
483 " Port address: %03X\n"
484 " BIOS segment: %05X\n"
485 " Interrupt: %u\n"
486 " DMA channel: %u\n"
487 " H/A SCSI ID: %u\n"
488 " Subversion: %u\n",
489 config.port_address, config.bios_segment, config.interrupt,
490 config.dma_channel, config.ha_scsi_id, config.subversion);
491 #endif
492 config.host_number = hostnum;
493 scsi_hosts[hostnum].this_id = config.ha_scsi_id;
494 scsi_hosts[hostnum].unchecked_isa_dma = (config.subversion != U34F);
495
496 #if ULTRASTOR_MAX_CMDS > 1
497 config.mscp_free = ~0;
498 #endif
499
500 if (request_irq(config.interrupt, ultrastor_interrupt)) {
501 printk("Unable to allocate IRQ%u for UltraStor controller.\n",
502 config.interrupt);
503 return FALSE;
504 }
505 if (config.dma_channel && request_dma(config.dma_channel)) {
506 printk("Unable to allocate DMA channel %u for UltraStor controller.\n",
507 config.dma_channel);
508 free_irq(config.interrupt);
509 return FALSE;
510 }
511 scsi_hosts[hostnum].sg_tablesize = ULTRASTOR_14F_MAX_SG;
512 printk("UltraStor driver version" VERSION ". Using %d SG lists.\n",
513 ULTRASTOR_14F_MAX_SG);
514
515 return TRUE;
516 }
517
518 static int ultrastor_24f_detect(int hostnum)
519 {
520 register int i;
521
522 #if (ULTRASTOR_DEBUG & UD_DETECT)
523 printk("US24F: detect");
524 #endif
525
526
527 for (i = 1; i < 15; i++)
528 {
529 unsigned char config_1, config_2;
530 unsigned short addr = (i << 12) | ULTRASTOR_24F_PORT;
531
532 if (inb(addr) != US24F_PRODUCT_ID_0 &&
533 inb(addr+1) != US24F_PRODUCT_ID_1 &&
534 inb(addr+2) != US24F_PRODUCT_ID_2)
535 continue;
536
537 config.revision = inb(addr+3);
538 config.slot = i;
539 if (! (inb(addr+4) & 1))
540 {
541 #if (ULTRASTOR_DEBUG & UD_DETECT)
542 printk("U24F: found disabled card in slot %u\n", i);
543 #endif
544 continue;
545 }
546 #if (ULTRASTOR_DEBUG & UD_DETECT)
547 printk("U24F: found card in slot %u\n", i);
548 #endif
549 config_1 = inb(addr + 5);
550 config.bios_segment = bios_segment_table[config_1 & 7];
551 switch(config_1 >> 4)
552 {
553 case 1:
554 config.interrupt = 15;
555 break;
556 case 2:
557 config.interrupt = 14;
558 break;
559 case 4:
560 config.interrupt = 11;
561 break;
562 case 8:
563 config.interrupt = 10;
564 break;
565 default:
566 printk("U24F: invalid IRQ\n");
567 return FALSE;
568 }
569 if (request_irq(config.interrupt, ultrastor_interrupt))
570 {
571 printk("Unable to allocate IRQ%u for UltraStor controller.\n",
572 config.interrupt);
573 return FALSE;
574 }
575
576
577 config.port_address = addr;
578 config.doorbell_address = addr + 12;
579 config.ogm_address = addr + 0x17;
580 config.icm_address = addr + 0x1C;
581 config_2 = inb(addr + 7);
582 config.ha_scsi_id = config_2 & 7;
583 config.heads = mapping_table[(config_2 >> 3) & 3].heads;
584 config.sectors = mapping_table[(config_2 >> 3) & 3].sectors;
585 #if (ULTRASTOR_DEBUG & UD_DETECT)
586 printk("US24F: detect: detect succeeded\n"
587 " Port address: %03X\n"
588 " BIOS segment: %05X\n"
589 " Interrupt: %u\n"
590 " H/A SCSI ID: %u\n",
591 config.port_address, config.bios_segment,
592 config.interrupt, config.ha_scsi_id);
593 #endif
594 config.host_number = hostnum;
595 scsi_hosts[hostnum].this_id = config.ha_scsi_id;
596 scsi_hosts[hostnum].unchecked_isa_dma = 0;
597 scsi_hosts[hostnum].sg_tablesize = ULTRASTOR_14F_MAX_SG;
598
599 #if ULTRASTOR_MAX_CMDS > 1
600 config.mscp_free = ~0;
601 #endif
602
603 outb(0, addr + 0x16);
604 outb(0, addr + 0x1B);
605
606
607
608 outb(ultrastor_bus_reset ? 0xc2 : 0x82, LCL_DOORBELL_MASK(addr+12));
609 outb(0x02, SYS_DOORBELL_MASK(addr+12));
610 printk("UltraStor driver version " VERSION ". Using %d SG lists.\n",
611 ULTRASTOR_14F_MAX_SG);
612 return TRUE;
613 }
614 return FALSE;
615 }
616
617 int ultrastor_detect(int hostnum)
618 {
619 return ultrastor_14f_detect(hostnum) || ultrastor_24f_detect(hostnum);
620 }
621
622 const char *ultrastor_info(void)
623 {
624 static char buf[64];
625
626 if (config.slot)
627 sprintf(buf, "UltraStor 24F SCSI @ Slot %u IRQ%u\n",
628 config.slot, config.interrupt);
629 else if (config.subversion)
630 sprintf(buf, "UltraStor 34F SCSI @ Port %03X BIOS %05X IRQ%u\n",
631 config.port_address, (int)config.bios_segment,
632 config.interrupt);
633 else
634 sprintf(buf, "UltraStor 14F SCSI @ Port %03X BIOS %05X IRQ%u DMA%u\n",
635 config.port_address, (int)config.bios_segment,
636 config.interrupt, config.dma_channel);
637 return buf;
638 }
639
640 static inline void build_sg_list(register struct mscp *mscp, Scsi_Cmnd *SCpnt)
641 {
642 struct scatterlist *sl;
643 long transfer_length = 0;
644 int i, max;
645
646 sl = (struct scatterlist *) SCpnt->request_buffer;
647 max = SCpnt->use_sg;
648 for (i = 0; i < max; i++) {
649 mscp->sglist[i].address = (unsigned int)sl[i].address;
650 mscp->sglist[i].num_bytes = sl[i].length;
651 transfer_length += sl[i].length;
652 }
653 mscp->number_of_sg_list = max;
654 mscp->transfer_data = (unsigned int)mscp->sglist;
655
656
657
658 mscp->transfer_data_length = transfer_length;
659 }
660
661 int ultrastor_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
662 {
663 register struct mscp *my_mscp;
664 #if ULTRASTOR_MAX_CMDS > 1
665 int mscp_index;
666 #endif
667 unsigned int status;
668 int flags;
669
670
671 if ((config.mscp_free & ((1U << ULTRASTOR_MAX_CMDS) - 1)) == 0)
672 panic("ultrastor_queuecommand: no free MSCP\n");
673 mscp_index = find_and_clear_bit_16(&config.mscp_free);
674
675
676 if (xchgb(0xff, &config.aborted[mscp_index]) != 0)
677 {
678 status = DID_ABORT << 16;
679 goto aborted;
680 }
681
682 my_mscp = &config.mscp[mscp_index];
683
684 #if 1
685
686 *(unsigned char *)my_mscp = OP_SCSI | (DTD_SCSI << 3);
687 #else
688 my_mscp->opcode = OP_SCSI;
689 my_mscp->xdir = DTD_SCSI;
690 my_mscp->dcn = FALSE;
691 #endif
692
693
694
695
696
697
698
699 my_mscp->ca = scsi_devices[SCpnt->index].type != TYPE_TAPE;
700 my_mscp->target_id = SCpnt->target;
701 my_mscp->ch_no = 0;
702 my_mscp->lun = SCpnt->lun;
703 if (SCpnt->use_sg) {
704
705 my_mscp->sg = TRUE;
706 build_sg_list(my_mscp, SCpnt);
707 } else {
708
709 my_mscp->sg = FALSE;
710 my_mscp->transfer_data = (unsigned int)SCpnt->request_buffer;
711 my_mscp->transfer_data_length = SCpnt->request_bufflen;
712 }
713 my_mscp->command_link = 0;
714 my_mscp->scsi_command_link_id = 0;
715 my_mscp->length_of_sense_byte = sizeof SCpnt->sense_buffer;
716 my_mscp->length_of_scsi_cdbs = COMMAND_SIZE(*(unsigned char *)SCpnt->cmnd);
717 memcpy(my_mscp->scsi_cdbs, SCpnt->cmnd, my_mscp->length_of_scsi_cdbs);
718 my_mscp->adapter_status = 0;
719 my_mscp->target_status = 0;
720 my_mscp->sense_data = (unsigned int)&SCpnt->sense_buffer;
721 my_mscp->done = done;
722 my_mscp->SCint = SCpnt;
723 SCpnt->host_scribble = (unsigned char *)my_mscp;
724
725
726
727
728 retry:
729 if (config.slot)
730 while (inb(config.ogm_address - 1) != 0 &&
731 config.aborted[mscp_index] == 0xff);
732
733
734
735 while ((inb(LCL_DOORBELL_INTR(config.doorbell_address)) &
736 (config.slot ? 2 : 1))
737 && config.aborted[mscp_index] == 0xff);
738
739
740
741
742 save_flags(flags);
743 cli();
744
745 if (inb(LCL_DOORBELL_INTR(config.doorbell_address)) &
746 (config.slot ? 2 : 1))
747 {
748 restore_flags(flags);
749 goto retry;
750 }
751
752 status = xchgb(0, &config.aborted[mscp_index]);
753 if (status != 0xff) {
754 restore_flags(flags);
755
756 #if ULTRASTOR_DEBUG & (UD_COMMAND | UD_ABORT)
757 printk("USx4F: queuecommand: aborted\n");
758 #if ULTRASTOR_MAX_CMDS > 1
759 log_ultrastor_abort(&config, mscp_index);
760 #endif
761 #endif
762 status <<= 16;
763
764 aborted:
765 set_bit(mscp_index, &config.mscp_free);
766
767
768 #if ULTRASTOR_MAX_CMDS > 1
769 SCpnt->result = status;
770 done(SCpnt);
771 return 0;
772 #else
773 return status;
774 #endif
775 }
776
777
778 outl((unsigned int)my_mscp, config.ogm_address);
779
780
781 if (config.slot) {
782
783 outb(1, config.ogm_address - 1);
784 outb(0x2, LCL_DOORBELL_INTR(config.doorbell_address));
785 } else {
786 outb(0x1, LCL_DOORBELL_INTR(config.doorbell_address));
787 }
788
789 restore_flags(flags);
790
791 #if (ULTRASTOR_DEBUG & UD_COMMAND)
792 printk("USx4F: queuecommand: returning\n");
793 #endif
794
795 return 0;
796 }
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813 int ultrastor_abort(Scsi_Cmnd *SCpnt, int code)
814 {
815 #if ULTRASTOR_DEBUG & UD_ABORT
816 char out[108];
817 unsigned char icm_status = 0, ogm_status = 0;
818 unsigned int icm_addr = 0, ogm_addr = 0;
819 #endif
820 unsigned int mscp_index;
821 unsigned char old_aborted;
822 void (*done)(Scsi_Cmnd *);
823
824 if(config.slot) return 0;
825
826 mscp_index = ((struct mscp *)SCpnt->host_scribble) - config.mscp;
827 if (mscp_index >= ULTRASTOR_MAX_CMDS)
828 panic("Ux4F aborting invalid MSCP");
829
830 #if ULTRASTOR_DEBUG & UD_ABORT
831 if (config.slot)
832 {
833 int port0 = (config.slot << 12) | 0xc80;
834 int i;
835 int flags;
836 save_flags(flags);
837 cli();
838 strcpy(out, "OGM %d:%x ICM %d:%x ports: ");
839 for (i = 0; i < 16; i++)
840 {
841 unsigned char p = inb(port0 + i);
842 out[28 + i * 3] = "0123456789abcdef"[p >> 4];
843 out[29 + i * 3] = "0123456789abcdef"[p & 15];
844 out[30 + i * 3] = ' ';
845 }
846 out[28 + i * 3] = '\n';
847 out[29 + i * 3] = 0;
848 ogm_status = inb(port0 + 22);
849 ogm_addr = inl(port0 + 23);
850 icm_status = inb(port0 + 27);
851 icm_addr = inl(port0 + 28);
852 restore_flags(flags);
853 }
854
855
856
857
858 if (config.slot ? inb(config.icm_address - 1) == 2 :
859 (inb(SYS_DOORBELL_INTR(config.doorbell_address)) & 1))
860 {
861 int flags;
862 save_flags(flags);
863 printk("Ux4F: abort while completed command pending\n");
864 restore_flags(flags);
865 cli();
866 ultrastor_interrupt(0);
867 restore_flags(flags);
868 return 0;
869 }
870 #endif
871
872 old_aborted = xchgb(code ? code : DID_ABORT, &config.aborted[mscp_index]);
873
874
875
876 if (old_aborted == 0xff)
877 return 0;
878
879
880
881 if (config.slot && inb(config.ogm_address - 1) == 0)
882 {
883 int flags;
884
885 save_flags(flags);
886 cli();
887 outl((int)&config.mscp[mscp_index], config.ogm_address);
888 inb(0xc80);
889 outb(0x80, config.ogm_address - 1);
890 outb(0x2, LCL_DOORBELL_INTR(config.doorbell_address));
891 #if ULTRASTOR_DEBUG & UD_ABORT
892 log_ultrastor_abort(&config, mscp_index);
893 printk(out, ogm_status, ogm_addr, icm_status, icm_addr);
894 #endif
895 restore_flags(flags);
896 return 0;
897 }
898
899 #if ULTRASTOR_DEBUG & UD_ABORT
900 log_ultrastor_abort(&config, mscp_index);
901 #endif
902
903
904
905
906
907
908 #if ULTRASTOR_DEBUG & UD_ABORT
909 if (config.mscp[mscp_index].SCint != SCpnt)
910 printk("abort: command mismatch, %x != %x\n",
911 config.mscp[mscp_index].SCint, SCpnt);
912 #endif
913 if (config.mscp[mscp_index].SCint == 0)
914 return 1;
915
916 if (config.mscp[mscp_index].SCint != SCpnt) panic("Bad abort");
917 config.mscp[mscp_index].SCint = 0;
918 done = config.mscp[mscp_index].done;
919 config.mscp[mscp_index].done = 0;
920 SCpnt->result = DID_ABORT << 16;
921
922 done(SCpnt);
923
924
925 return 0;
926
927 }
928
929 int ultrastor_reset(Scsi_Cmnd * SCpnt)
930 {
931 int flags;
932 register int i;
933 #if (ULTRASTOR_DEBUG & UD_RESET)
934 printk("US14F: reset: called\n");
935 #endif
936
937 if(config.slot) {
938 if (SCpnt) SCpnt->flags |= NEEDS_JUMPSTART;
939 return 0;
940 };
941
942 save_flags(flags);
943 cli();
944
945
946
947 outb(0xc0, LCL_DOORBELL_INTR(config.doorbell_address));
948 if (config.slot)
949 {
950 outb(0, config.ogm_address - 1);
951 outb(0, config.icm_address - 1);
952 }
953
954 #if ULTRASTOR_MAX_CMDS == 1
955 if (config.mscp_busy && config.mscp->done && config.mscp->SCint)
956 {
957 config.mscp->SCint->result = DID_RESET << 16;
958 config.mscp->done(config.mscp->SCint);
959 }
960 config.mscp->SCint = 0;
961 #else
962 for (i = 0; i < ULTRASTOR_MAX_CMDS; i++)
963 {
964 if (! (config.mscp_free & (1 << i)) &&
965 config.mscp[i].done && config.mscp[i].SCint)
966 {
967 config.mscp[i].SCint->result = DID_RESET << 16;
968 config.mscp[i].done(config.mscp[i].SCint);
969 config.mscp[i].done = 0;
970 }
971 config.mscp[i].SCint = 0;
972 }
973 #endif
974
975 memset((unsigned char *)config.aborted, 0, sizeof config.aborted);
976 #if ULTRASTOR_MAX_CMDS == 1
977 config.mscp_busy = 0;
978 #else
979 config.mscp_free = ~0;
980 #endif
981
982 restore_flags(flags);
983 return 0;
984
985 }
986
987 int ultrastor_biosparam(int size, int dev, int * dkinfo)
988 {
989 unsigned int s = config.heads * config.sectors;
990
991 dkinfo[0] = config.heads;
992 dkinfo[1] = config.sectors;
993 dkinfo[2] = size / s;
994 if (dkinfo[2] > 1024)
995 dkinfo[2] = 1024;
996 return 0;
997 }
998
999 static void ultrastor_interrupt(int cpl)
1000 {
1001 unsigned int status;
1002 #if ULTRASTOR_MAX_CMDS > 1
1003 unsigned int mscp_index;
1004 #endif
1005 register struct mscp *mscp;
1006 void (*done)(Scsi_Cmnd *);
1007 Scsi_Cmnd *SCtmp;
1008
1009 #if ULTRASTOR_MAX_CMDS == 1
1010 mscp = &config.mscp[0];
1011 #else
1012 mscp = (struct mscp *)inl(config.icm_address);
1013 mscp_index = mscp - config.mscp;
1014 if (mscp_index >= ULTRASTOR_MAX_CMDS) {
1015 printk("Ux4F interrupt: bad MSCP address %x\n", (unsigned int) mscp);
1016
1017
1018 ultrastor_reset(NULL);
1019 return;
1020 }
1021 #endif
1022
1023
1024 if (config.slot) {
1025 unsigned char icm_status = inb(config.icm_address - 1);
1026 #if ULTRASTOR_DEBUG & (UD_INTERRUPT|UD_ERROR|UD_ABORT)
1027 if (icm_status != 1 && icm_status != 2)
1028 printk("US24F: ICM status %x for MSCP %d (%x)\n", icm_status,
1029 mscp_index, (unsigned int) mscp);
1030 #endif
1031
1032
1033 outb(2, SYS_DOORBELL_INTR(config.doorbell_address));
1034 outb(0, config.icm_address - 1);
1035 if (icm_status == 4) {
1036 printk("UltraStor abort command failed\n");
1037 return;
1038 }
1039 if (icm_status == 3) {
1040 void (*done)(Scsi_Cmnd *) = mscp->done;
1041 if (done) {
1042 mscp->done = 0;
1043 mscp->SCint->result = DID_ABORT << 16;
1044 done(mscp->SCint);
1045 }
1046 return;
1047 }
1048 } else {
1049 outb(1, SYS_DOORBELL_INTR(config.doorbell_address));
1050 }
1051
1052 SCtmp = mscp->SCint;
1053 mscp->SCint = NULL;
1054
1055 if (SCtmp == 0)
1056 {
1057 #if ULTRASTOR_DEBUG & (UD_ABORT|UD_INTERRUPT)
1058 printk("MSCP %d (%x): no command\n", mscp_index, (unsigned int) mscp);
1059 #endif
1060 #if ULTRASTOR_MAX_CMDS == 1
1061 config.mscp_busy = FALSE;
1062 #else
1063 set_bit(mscp_index, &config.mscp_free);
1064 #endif
1065 config.aborted[mscp_index] = 0;
1066 return;
1067 }
1068
1069
1070
1071
1072 done = mscp->done;
1073 mscp->done = 0;
1074
1075
1076 switch (mscp->adapter_status)
1077 {
1078 case 0:
1079 status = DID_OK << 16;
1080 break;
1081 case 0x01:
1082 case 0x02:
1083 case 0x03:
1084 default:
1085 status = DID_ERROR << 16;
1086 break;
1087 case 0x84:
1088 status = DID_ABORT << 16;
1089 break;
1090 case 0x91:
1091 status = DID_TIME_OUT << 16;
1092 break;
1093 }
1094
1095 SCtmp->result = status | mscp->target_status;
1096
1097 SCtmp->host_scribble = 0;
1098
1099
1100 #if ULTRASTOR_MAX_CMDS == 1
1101 config.mscp_busy = FALSE;
1102 #else
1103 set_bit(mscp_index, &config.mscp_free);
1104 #endif
1105
1106 #if ULTRASTOR_DEBUG & (UD_ABORT|UD_INTERRUPT)
1107 if (config.aborted[mscp_index])
1108 printk("Ux4 interrupt: MSCP %d (%x) aborted = %d\n",
1109 mscp_index, (unsigned int) mscp, config.aborted[mscp_index]);
1110 #endif
1111 config.aborted[mscp_index] = 0;
1112
1113 if (done)
1114 done(SCtmp);
1115 else
1116 printk("US14F: interrupt: unexpected interrupt\n");
1117
1118 if (config.slot ? inb(config.icm_address - 1) : (inb(SYS_DOORBELL_INTR(config.doorbell_address)) & 1))
1119 printk("Ux4F: multiple commands completed\n");
1120
1121 #if (ULTRASTOR_DEBUG & UD_INTERRUPT)
1122 printk("USx4F: interrupt: returning\n");
1123 #endif
1124 }