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 #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 #if ULTRASTOR_DEBUG & (UD_COMMAND | UD_ABORT)
306
307 static void log_ultrastor_abort(register struct ultrastor_config *config,
308 int command)
309 {
310 static char fmt[80] = "abort %d (%x); MSCP free pool: %x;";
311 register int i;
312 int flags;
313 save_flags(flags);
314 cli();
315
316 for (i = 0; i < ULTRASTOR_MAX_CMDS; i++)
317 {
318 fmt[20 + i*2] = ' ';
319 if (! (config->mscp_free & (1 << i)))
320 fmt[21 + i*2] = '0' + config->mscp[i].target_id;
321 else
322 fmt[21 + i*2] = '-';
323 }
324 fmt[20 + ULTRASTOR_MAX_CMDS * 2] = '\n';
325 fmt[21 + ULTRASTOR_MAX_CMDS * 2] = 0;
326 printk(fmt, command, &config->mscp[command], config->mscp_free);
327 restore_flags(flags);
328 }
329 #endif
330
331 static int ultrastor_14f_detect(int hostnum)
332 {
333 size_t i;
334 unsigned char in_byte, version_byte = 0;
335 struct config_1 {
336 unsigned char bios_segment: 3;
337 unsigned char removable_disks_as_fixed: 1;
338 unsigned char interrupt: 2;
339 unsigned char dma_channel: 2;
340 } config_1;
341 struct config_2 {
342 unsigned char ha_scsi_id: 3;
343 unsigned char mapping_mode: 2;
344 unsigned char bios_drive_number: 1;
345 unsigned char tfr_port: 2;
346 } config_2;
347
348 #if (ULTRASTOR_DEBUG & UD_DETECT)
349 printk("US14F: detect: called\n");
350 #endif
351
352
353 if (config.bios_segment)
354 return FALSE;
355
356 #ifdef PORT_OVERRIDE
357 if(check_region(PORT_OVERRIDE, 0xc)) {
358 printk("Ultrastor I/O space already in use\n");
359 return FALSE;
360 };
361 config.port_address = PORT_OVERRIDE;
362 #else
363 for (i = 0; i < ARRAY_SIZE(ultrastor_ports_14f); i++) {
364 if(check_region(ultrastor_ports_14f[i], 0x0c)) continue;
365 config.port_address = ultrastor_ports_14f[i];
366 #endif
367
368 #if (ULTRASTOR_DEBUG & UD_DETECT)
369 printk("US14F: detect: testing port address %03X\n", config.port_address);
370 #endif
371
372 in_byte = inb(U14F_PRODUCT_ID(config.port_address));
373 if (in_byte != US14F_PRODUCT_ID_0) {
374 #if (ULTRASTOR_DEBUG & UD_DETECT)
375 # ifdef PORT_OVERRIDE
376 printk("US14F: detect: wrong product ID 0 - %02X\n", in_byte);
377 # else
378 printk("US14F: detect: no adapter at port %03X\n", config.port_address);
379 # endif
380 #endif
381 #ifdef PORT_OVERRIDE
382 return FALSE;
383 #else
384 continue;
385 #endif
386 }
387 in_byte = inb(U14F_PRODUCT_ID(config.port_address) + 1);
388
389 if ((in_byte & 0xF0) != US14F_PRODUCT_ID_1) {
390 #if (ULTRASTOR_DEBUG & UD_DETECT)
391 # ifdef PORT_OVERRIDE
392 printk("US14F: detect: wrong product ID 1 - %02X\n", in_byte);
393 # else
394 printk("US14F: detect: no adapter at port %03X\n", config.port_address);
395 # endif
396 #endif
397 #ifdef PORT_OVERRIDE
398 return FALSE;
399 #else
400 continue;
401 #endif
402 }
403 version_byte = in_byte;
404 #ifndef PORT_OVERRIDE
405 break;
406 }
407 if (i == ARRAY_SIZE(ultrastor_ports_14f)) {
408 # if (ULTRASTOR_DEBUG & UD_DETECT)
409 printk("US14F: detect: no port address found!\n");
410 # endif
411 return FALSE;
412 }
413 #endif
414
415 #if (ULTRASTOR_DEBUG & UD_DETECT)
416 printk("US14F: detect: adapter found at port address %03X\n",
417 config.port_address);
418 #endif
419
420
421
422 outb(ultrastor_bus_reset ? 0xc2 : 0x82, LCL_DOORBELL_MASK(config.port_address));
423
424
425
426
427 snarf_region(config.port_address, 0x0c);
428
429 *(char *)&config_1 = inb(CONFIG(config.port_address + 0));
430 *(char *)&config_2 = inb(CONFIG(config.port_address + 1));
431 config.bios_segment = bios_segment_table[config_1.bios_segment];
432 config.doorbell_address = config.port_address;
433 config.ogm_address = config.port_address + 0x8;
434 config.icm_address = config.port_address + 0xC;
435 config.interrupt = interrupt_table_14f[config_1.interrupt];
436 config.ha_scsi_id = config_2.ha_scsi_id;
437 config.heads = mapping_table[config_2.mapping_mode].heads;
438 config.sectors = mapping_table[config_2.mapping_mode].sectors;
439 config.bios_drive_number = config_2.bios_drive_number;
440 config.subversion = (version_byte & 0x0F);
441 if (config.subversion == U34F)
442 config.dma_channel = 0;
443 else
444 config.dma_channel = dma_channel_table_14f[config_1.dma_channel];
445
446 if (!config.bios_segment) {
447 #if (ULTRASTOR_DEBUG & UD_DETECT)
448 printk("US14F: detect: not detected.\n");
449 #endif
450 return FALSE;
451 }
452
453
454 if (config.subversion != U34F)
455 if (!config.dma_channel || !(config_2.tfr_port & 0x2)) {
456 #if (ULTRASTOR_DEBUG & UD_DETECT)
457 printk("US14F: detect: consistancy check failed\n");
458 #endif
459 return FALSE;
460 }
461
462
463
464
465
466
467 #if (ULTRASTOR_DEBUG & UD_DETECT)
468 printk("US14F: detect: detect succeeded\n"
469 " Port address: %03X\n"
470 " BIOS segment: %05X\n"
471 " Interrupt: %u\n"
472 " DMA channel: %u\n"
473 " H/A SCSI ID: %u\n"
474 " Subversion: %u\n",
475 config.port_address, config.bios_segment, config.interrupt,
476 config.dma_channel, config.ha_scsi_id, config.subversion);
477 #endif
478 config.host_number = hostnum;
479 scsi_hosts[hostnum].this_id = config.ha_scsi_id;
480 scsi_hosts[hostnum].unchecked_isa_dma = (config.subversion != U34F);
481
482 #if ULTRASTOR_MAX_CMDS > 1
483 config.mscp_free = ~0;
484 #endif
485
486 if (request_irq(config.interrupt, ultrastor_interrupt)) {
487 printk("Unable to allocate IRQ%u for UltraStor controller.\n",
488 config.interrupt);
489 return FALSE;
490 }
491 if (config.dma_channel && request_dma(config.dma_channel)) {
492 printk("Unable to allocate DMA channel %u for UltraStor controller.\n",
493 config.dma_channel);
494 free_irq(config.interrupt);
495 return FALSE;
496 }
497 scsi_hosts[hostnum].sg_tablesize = ULTRASTOR_14F_MAX_SG;
498 printk("UltraStor driver version" VERSION ". Using %d SG lists.\n",
499 ULTRASTOR_14F_MAX_SG);
500
501 return TRUE;
502 }
503
504 static int ultrastor_24f_detect(int hostnum)
505 {
506 register int i;
507
508 #if (ULTRASTOR_DEBUG & UD_DETECT)
509 printk("US24F: detect");
510 #endif
511
512
513 for (i = 1; i < 15; i++)
514 {
515 unsigned char config_1, config_2;
516 unsigned short addr = (i << 12) | ULTRASTOR_24F_PORT;
517
518 if (inb(addr) != US24F_PRODUCT_ID_0 &&
519 inb(addr+1) != US24F_PRODUCT_ID_1 &&
520 inb(addr+2) != US24F_PRODUCT_ID_2)
521 continue;
522
523 config.revision = inb(addr+3);
524 config.slot = i;
525 if (! (inb(addr+4) & 1))
526 {
527 #if (ULTRASTOR_DEBUG & UD_DETECT)
528 printk("U24F: found disabled card in slot %u\n", i);
529 #endif
530 continue;
531 }
532 #if (ULTRASTOR_DEBUG & UD_DETECT)
533 printk("U24F: found card in slot %u\n", i);
534 #endif
535 config_1 = inb(addr + 5);
536 config.bios_segment = bios_segment_table[config_1 & 7];
537 switch(config_1 >> 4)
538 {
539 case 1:
540 config.interrupt = 15;
541 break;
542 case 2:
543 config.interrupt = 14;
544 break;
545 case 4:
546 config.interrupt = 11;
547 break;
548 case 8:
549 config.interrupt = 10;
550 break;
551 default:
552 printk("U24F: invalid IRQ\n");
553 return FALSE;
554 }
555 if (request_irq(config.interrupt, ultrastor_interrupt))
556 {
557 printk("Unable to allocate IRQ%u for UltraStor controller.\n",
558 config.interrupt);
559 return FALSE;
560 }
561
562
563 config.port_address = addr;
564 config.doorbell_address = addr + 12;
565 config.ogm_address = addr + 0x17;
566 config.icm_address = addr + 0x1C;
567 config_2 = inb(addr + 7);
568 config.ha_scsi_id = config_2 & 7;
569 config.heads = mapping_table[(config_2 >> 3) & 3].heads;
570 config.sectors = mapping_table[(config_2 >> 3) & 3].sectors;
571 #if (ULTRASTOR_DEBUG & UD_DETECT)
572 printk("US24F: detect: detect succeeded\n"
573 " Port address: %03X\n"
574 " BIOS segment: %05X\n"
575 " Interrupt: %u\n"
576 " H/A SCSI ID: %u\n",
577 config.port_address, config.bios_segment,
578 config.interrupt, config.ha_scsi_id);
579 #endif
580 config.host_number = hostnum;
581 scsi_hosts[hostnum].this_id = config.ha_scsi_id;
582 scsi_hosts[hostnum].unchecked_isa_dma = 0;
583 scsi_hosts[hostnum].sg_tablesize = ULTRASTOR_14F_MAX_SG;
584
585 #if ULTRASTOR_MAX_CMDS > 1
586 config.mscp_free = ~0;
587 #endif
588
589 outb(0, addr + 0x16);
590 outb(0, addr + 0x1B);
591
592
593
594 outb(ultrastor_bus_reset ? 0xc2 : 0x82, LCL_DOORBELL_MASK(addr+12));
595 outb(0x02, SYS_DOORBELL_MASK(addr+12));
596 printk("UltraStor driver version " VERSION ". Using %d SG lists.\n",
597 ULTRASTOR_14F_MAX_SG);
598 return TRUE;
599 }
600 return FALSE;
601 }
602
603 int ultrastor_detect(int hostnum)
604 {
605 return ultrastor_14f_detect(hostnum) || ultrastor_24f_detect(hostnum);
606 }
607
608 const char *ultrastor_info(void)
609 {
610 static char buf[64];
611
612 if (config.slot)
613 sprintf(buf, "UltraStor 24F SCSI @ Slot %u IRQ%u\n",
614 config.slot, config.interrupt);
615 else if (config.subversion)
616 sprintf(buf, "UltraStor 34F SCSI @ Port %03X BIOS %05X IRQ%u\n",
617 config.port_address, (int)config.bios_segment,
618 config.interrupt);
619 else
620 sprintf(buf, "UltraStor 14F SCSI @ Port %03X BIOS %05X IRQ%u DMA%u\n",
621 config.port_address, (int)config.bios_segment,
622 config.interrupt, config.dma_channel);
623 return buf;
624 }
625
626 static inline void build_sg_list(register struct mscp *mscp, Scsi_Cmnd *SCpnt)
627 {
628 struct scatterlist *sl;
629 long transfer_length = 0;
630 int i, max;
631
632 sl = (struct scatterlist *) SCpnt->request_buffer;
633 max = SCpnt->use_sg;
634 for (i = 0; i < max; i++) {
635 mscp->sglist[i].address = (unsigned int)sl[i].address;
636 mscp->sglist[i].num_bytes = sl[i].length;
637 transfer_length += sl[i].length;
638 }
639 mscp->number_of_sg_list = max;
640 mscp->transfer_data = (unsigned int)mscp->sglist;
641
642
643
644 mscp->transfer_data_length = transfer_length;
645 }
646
647 int ultrastor_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
648 {
649 register struct mscp *my_mscp;
650 #if ULTRASTOR_MAX_CMDS > 1
651 int mscp_index;
652 #endif
653 unsigned int status;
654 int flags;
655
656
657 if ((config.mscp_free & ((1U << ULTRASTOR_MAX_CMDS) - 1)) == 0)
658 panic("ultrastor_queuecommand: no free MSCP\n");
659 mscp_index = find_and_clear_bit_16(&config.mscp_free);
660
661
662 if (xchgb(0xff, &config.aborted[mscp_index]) != 0)
663 {
664 status = DID_ABORT << 16;
665 goto aborted;
666 }
667
668 my_mscp = &config.mscp[mscp_index];
669
670 #if 1
671
672 *(unsigned char *)my_mscp = OP_SCSI | (DTD_SCSI << 3);
673 #else
674 my_mscp->opcode = OP_SCSI;
675 my_mscp->xdir = DTD_SCSI;
676 my_mscp->dcn = FALSE;
677 #endif
678
679
680
681
682
683
684
685 my_mscp->ca = scsi_devices[SCpnt->index].type != TYPE_TAPE;
686 my_mscp->target_id = SCpnt->target;
687 my_mscp->ch_no = 0;
688 my_mscp->lun = SCpnt->lun;
689 if (SCpnt->use_sg) {
690
691 my_mscp->sg = TRUE;
692 build_sg_list(my_mscp, SCpnt);
693 } else {
694
695 my_mscp->sg = FALSE;
696 my_mscp->transfer_data = (unsigned int)SCpnt->request_buffer;
697 my_mscp->transfer_data_length = SCpnt->request_bufflen;
698 }
699 my_mscp->command_link = 0;
700 my_mscp->scsi_command_link_id = 0;
701 my_mscp->length_of_sense_byte = sizeof SCpnt->sense_buffer;
702 my_mscp->length_of_scsi_cdbs = COMMAND_SIZE(*(unsigned char *)SCpnt->cmnd);
703 memcpy(my_mscp->scsi_cdbs, SCpnt->cmnd, my_mscp->length_of_scsi_cdbs);
704 my_mscp->adapter_status = 0;
705 my_mscp->target_status = 0;
706 my_mscp->sense_data = (unsigned int)&SCpnt->sense_buffer;
707 my_mscp->done = done;
708 my_mscp->SCint = SCpnt;
709 SCpnt->host_scribble = (unsigned char *)my_mscp;
710
711
712
713
714 retry:
715 if (config.slot)
716 while (inb(config.ogm_address - 1) != 0 &&
717 config.aborted[mscp_index] == 0xff);
718
719
720
721 while ((inb(LCL_DOORBELL_INTR(config.doorbell_address)) &
722 (config.slot ? 2 : 1))
723 && config.aborted[mscp_index] == 0xff);
724
725
726
727
728 save_flags(flags);
729 cli();
730
731 if (inb(LCL_DOORBELL_INTR(config.doorbell_address)) &
732 (config.slot ? 2 : 1))
733 {
734 restore_flags(flags);
735 goto retry;
736 }
737
738 status = xchgb(0, &config.aborted[mscp_index]);
739 if (status != 0xff) {
740 restore_flags(flags);
741
742 #if ULTRASTOR_DEBUG & (UD_COMMAND | UD_ABORT)
743 printk("USx4F: queuecommand: aborted\n");
744 #if ULTRASTOR_MAX_CMDS > 1
745 log_ultrastor_abort(&config, mscp_index);
746 #endif
747 #endif
748 status <<= 16;
749
750 aborted:
751 set_bit(mscp_index, &config.mscp_free);
752
753
754 #if ULTRASTOR_MAX_CMDS > 1
755 SCpnt->result = status;
756 done(SCpnt);
757 return 0;
758 #else
759 return status;
760 #endif
761 }
762
763
764 outl((unsigned int)my_mscp, config.ogm_address);
765
766
767 if (config.slot) {
768
769 outb(1, config.ogm_address - 1);
770 outb(0x2, LCL_DOORBELL_INTR(config.doorbell_address));
771 } else {
772 outb(0x1, LCL_DOORBELL_INTR(config.doorbell_address));
773 }
774
775 restore_flags(flags);
776
777 #if (ULTRASTOR_DEBUG & UD_COMMAND)
778 printk("USx4F: queuecommand: returning\n");
779 #endif
780
781 return 0;
782 }
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799 int ultrastor_abort(Scsi_Cmnd *SCpnt)
800 {
801 #if ULTRASTOR_DEBUG & UD_ABORT
802 char out[108];
803 unsigned char icm_status = 0, ogm_status = 0;
804 unsigned int icm_addr = 0, ogm_addr = 0;
805 #endif
806 unsigned int mscp_index;
807 unsigned char old_aborted;
808 void (*done)(Scsi_Cmnd *);
809
810 if(config.slot)
811 return SCSI_ABORT_SNOOZE;
812
813 mscp_index = ((struct mscp *)SCpnt->host_scribble) - config.mscp;
814 if (mscp_index >= ULTRASTOR_MAX_CMDS)
815 panic("Ux4F aborting invalid MSCP");
816
817 #if ULTRASTOR_DEBUG & UD_ABORT
818 if (config.slot)
819 {
820 int port0 = (config.slot << 12) | 0xc80;
821 int i;
822 int flags;
823 save_flags(flags);
824 cli();
825 strcpy(out, "OGM %d:%x ICM %d:%x ports: ");
826 for (i = 0; i < 16; i++)
827 {
828 unsigned char p = inb(port0 + i);
829 out[28 + i * 3] = "0123456789abcdef"[p >> 4];
830 out[29 + i * 3] = "0123456789abcdef"[p & 15];
831 out[30 + i * 3] = ' ';
832 }
833 out[28 + i * 3] = '\n';
834 out[29 + i * 3] = 0;
835 ogm_status = inb(port0 + 22);
836 ogm_addr = inl(port0 + 23);
837 icm_status = inb(port0 + 27);
838 icm_addr = inl(port0 + 28);
839 restore_flags(flags);
840 }
841
842
843
844
845 if (config.slot ? inb(config.icm_address - 1) == 2 :
846 (inb(SYS_DOORBELL_INTR(config.doorbell_address)) & 1))
847 {
848 int flags;
849 save_flags(flags);
850 printk("Ux4F: abort while completed command pending\n");
851 restore_flags(flags);
852 cli();
853 ultrastor_interrupt(0);
854 restore_flags(flags);
855 return SCSI_ABORT_SUCCESS;
856 }
857 #endif
858
859 old_aborted = xchgb(DID_ABORT, &config.aborted[mscp_index]);
860
861
862
863 if (old_aborted == 0xff)
864 return SCSI_ABORT_SUCCESS;
865
866
867
868 if (config.slot && inb(config.ogm_address - 1) == 0)
869 {
870 int flags;
871
872 save_flags(flags);
873 cli();
874 outl((int)&config.mscp[mscp_index], config.ogm_address);
875 inb(0xc80);
876 outb(0x80, config.ogm_address - 1);
877 outb(0x2, LCL_DOORBELL_INTR(config.doorbell_address));
878 #if ULTRASTOR_DEBUG & UD_ABORT
879 log_ultrastor_abort(&config, mscp_index);
880 printk(out, ogm_status, ogm_addr, icm_status, icm_addr);
881 #endif
882 restore_flags(flags);
883 return SCSI_ABORT_PENDING;
884 }
885
886 #if ULTRASTOR_DEBUG & UD_ABORT
887 log_ultrastor_abort(&config, mscp_index);
888 #endif
889
890
891
892
893
894
895
896
897
898
899
900 #if ULTRASTOR_DEBUG & UD_ABORT
901 if (config.mscp[mscp_index].SCint != SCpnt)
902 printk("abort: command mismatch, %x != %x\n",
903 config.mscp[mscp_index].SCint, SCpnt);
904 #endif
905 if (config.mscp[mscp_index].SCint == 0)
906 return SCSI_ABORT_NOT_RUNNING;
907
908 if (config.mscp[mscp_index].SCint != SCpnt) panic("Bad abort");
909 config.mscp[mscp_index].SCint = 0;
910 done = config.mscp[mscp_index].done;
911 config.mscp[mscp_index].done = 0;
912 SCpnt->result = DID_ABORT << 16;
913
914 done(SCpnt);
915
916
917 return SCSI_ABORT_SUCCESS;
918
919 }
920
921 int ultrastor_reset(Scsi_Cmnd * SCpnt)
922 {
923 int flags;
924 register int i;
925 #if (ULTRASTOR_DEBUG & UD_RESET)
926 printk("US14F: reset: called\n");
927 #endif
928
929 if(config.slot)
930 return SCSI_RESET_SNOOZE;
931
932 save_flags(flags);
933 cli();
934
935
936
937 outb(0xc0, LCL_DOORBELL_INTR(config.doorbell_address));
938 if (config.slot)
939 {
940 outb(0, config.ogm_address - 1);
941 outb(0, config.icm_address - 1);
942 }
943
944 #if ULTRASTOR_MAX_CMDS == 1
945 if (config.mscp_busy && config.mscp->done && config.mscp->SCint)
946 {
947 config.mscp->SCint->result = DID_RESET << 16;
948 config.mscp->done(config.mscp->SCint);
949 }
950 config.mscp->SCint = 0;
951 #else
952 for (i = 0; i < ULTRASTOR_MAX_CMDS; i++)
953 {
954 if (! (config.mscp_free & (1 << i)) &&
955 config.mscp[i].done && config.mscp[i].SCint)
956 {
957 config.mscp[i].SCint->result = DID_RESET << 16;
958 config.mscp[i].done(config.mscp[i].SCint);
959 config.mscp[i].done = 0;
960 }
961 config.mscp[i].SCint = 0;
962 }
963 #endif
964
965
966
967
968 memset((unsigned char *)config.aborted, 0, sizeof config.aborted);
969 #if ULTRASTOR_MAX_CMDS == 1
970 config.mscp_busy = 0;
971 #else
972 config.mscp_free = ~0;
973 #endif
974
975 restore_flags(flags);
976 return SCSI_RESET_SUCCESS;
977
978 }
979
980 int ultrastor_biosparam(int size, int dev, int * dkinfo)
981 {
982 unsigned int s = config.heads * config.sectors;
983
984 dkinfo[0] = config.heads;
985 dkinfo[1] = config.sectors;
986 dkinfo[2] = size / s;
987 #if 0
988 if (dkinfo[2] > 1024)
989 dkinfo[2] = 1024;
990 #endif
991 return 0;
992 }
993
994 static void ultrastor_interrupt(int cpl)
995 {
996 unsigned int status;
997 #if ULTRASTOR_MAX_CMDS > 1
998 unsigned int mscp_index;
999 #endif
1000 register struct mscp *mscp;
1001 void (*done)(Scsi_Cmnd *);
1002 Scsi_Cmnd *SCtmp;
1003
1004 #if ULTRASTOR_MAX_CMDS == 1
1005 mscp = &config.mscp[0];
1006 #else
1007 mscp = (struct mscp *)inl(config.icm_address);
1008 mscp_index = mscp - config.mscp;
1009 if (mscp_index >= ULTRASTOR_MAX_CMDS) {
1010 printk("Ux4F interrupt: bad MSCP address %x\n", (unsigned int) mscp);
1011
1012
1013 ultrastor_reset(NULL);
1014 return;
1015 }
1016 #endif
1017
1018
1019 if (config.slot) {
1020 unsigned char icm_status = inb(config.icm_address - 1);
1021 #if ULTRASTOR_DEBUG & (UD_INTERRUPT|UD_ERROR|UD_ABORT)
1022 if (icm_status != 1 && icm_status != 2)
1023 printk("US24F: ICM status %x for MSCP %d (%x)\n", icm_status,
1024 mscp_index, (unsigned int) mscp);
1025 #endif
1026
1027
1028 outb(2, SYS_DOORBELL_INTR(config.doorbell_address));
1029 outb(0, config.icm_address - 1);
1030 if (icm_status == 4) {
1031 printk("UltraStor abort command failed\n");
1032 return;
1033 }
1034 if (icm_status == 3) {
1035 void (*done)(Scsi_Cmnd *) = mscp->done;
1036 if (done) {
1037 mscp->done = 0;
1038 mscp->SCint->result = DID_ABORT << 16;
1039 done(mscp->SCint);
1040 }
1041 return;
1042 }
1043 } else {
1044 outb(1, SYS_DOORBELL_INTR(config.doorbell_address));
1045 }
1046
1047 SCtmp = mscp->SCint;
1048 mscp->SCint = NULL;
1049
1050 if (SCtmp == 0)
1051 {
1052 #if ULTRASTOR_DEBUG & (UD_ABORT|UD_INTERRUPT)
1053 printk("MSCP %d (%x): no command\n", mscp_index, (unsigned int) mscp);
1054 #endif
1055 #if ULTRASTOR_MAX_CMDS == 1
1056 config.mscp_busy = FALSE;
1057 #else
1058 set_bit(mscp_index, &config.mscp_free);
1059 #endif
1060 config.aborted[mscp_index] = 0;
1061 return;
1062 }
1063
1064
1065
1066
1067 done = mscp->done;
1068 mscp->done = 0;
1069
1070
1071 switch (mscp->adapter_status)
1072 {
1073 case 0:
1074 status = DID_OK << 16;
1075 break;
1076 case 0x01:
1077 case 0x02:
1078 case 0x03:
1079 default:
1080 status = DID_ERROR << 16;
1081 break;
1082 case 0x84:
1083 status = DID_ABORT << 16;
1084 break;
1085 case 0x91:
1086 status = DID_TIME_OUT << 16;
1087 break;
1088 }
1089
1090 SCtmp->result = status | mscp->target_status;
1091
1092 SCtmp->host_scribble = 0;
1093
1094
1095 #if ULTRASTOR_MAX_CMDS == 1
1096 config.mscp_busy = FALSE;
1097 #else
1098 set_bit(mscp_index, &config.mscp_free);
1099 #endif
1100
1101 #if ULTRASTOR_DEBUG & (UD_ABORT|UD_INTERRUPT)
1102 if (config.aborted[mscp_index])
1103 printk("Ux4 interrupt: MSCP %d (%x) aborted = %d\n",
1104 mscp_index, (unsigned int) mscp, config.aborted[mscp_index]);
1105 #endif
1106 config.aborted[mscp_index] = 0;
1107
1108 if (done)
1109 done(SCtmp);
1110 else
1111 printk("US14F: interrupt: unexpected interrupt\n");
1112
1113 if (config.slot ? inb(config.icm_address - 1) : (inb(SYS_DOORBELL_INTR(config.doorbell_address)) & 1))
1114 printk("Ux4F: multiple commands completed\n");
1115
1116 #if (ULTRASTOR_DEBUG & UD_INTERRUPT)
1117 printk("USx4F: interrupt: returning\n");
1118 #endif
1119 }