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