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