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, struct pt_regs *);
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 unsigned long flags;
294
295 save_flags(flags);
296 cli();
297 if (*field == 0) panic("No free mscp");
298 asm("xorl %0,%0\n0:\tbsfw %1,%w0\n\tbtr %0,%1\n\tjnc 0b"
299 : "=&r" (rv), "=m" (*field) : "1" (*field));
300 restore_flags(flags);
301 return rv;
302 }
303
304
305
306
307
308
309
310
311
312 static inline unsigned char xchgb(unsigned char reg,
313 volatile unsigned char *mem)
314 {
315 __asm__ ("xchgb %0,%1" : "=q" (reg), "=m" (*mem) : "0" (reg));
316 return reg;
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(Scsi_Host_Template * tpnt)
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 request_region(config.port_address, 0x0c,"ultrastor");
442
443
444 *(char *)&config_1 = inb(CONFIG(config.port_address + 0));
445 *(char *)&config_2 = inb(CONFIG(config.port_address + 1));
446 config.bios_segment = bios_segment_table[config_1.bios_segment];
447 config.doorbell_address = config.port_address;
448 config.ogm_address = config.port_address + 0x8;
449 config.icm_address = config.port_address + 0xC;
450 config.interrupt = interrupt_table_14f[config_1.interrupt];
451 config.ha_scsi_id = config_2.ha_scsi_id;
452 config.heads = mapping_table[config_2.mapping_mode].heads;
453 config.sectors = mapping_table[config_2.mapping_mode].sectors;
454 config.bios_drive_number = config_2.bios_drive_number;
455 config.subversion = (version_byte & 0x0F);
456 if (config.subversion == U34F)
457 config.dma_channel = 0;
458 else
459 config.dma_channel = dma_channel_table_14f[config_1.dma_channel];
460
461 if (!config.bios_segment) {
462 #if (ULTRASTOR_DEBUG & UD_DETECT)
463 printk("US14F: detect: not detected.\n");
464 #endif
465 return FALSE;
466 }
467
468
469 if (config.subversion != U34F)
470 if (!config.dma_channel || !(config_2.tfr_port & 0x2)) {
471 #if (ULTRASTOR_DEBUG & UD_DETECT)
472 printk("US14F: detect: consistency check failed\n");
473 #endif
474 return FALSE;
475 }
476
477
478
479
480
481
482 #if (ULTRASTOR_DEBUG & UD_DETECT)
483 printk("US14F: detect: detect succeeded\n"
484 " Port address: %03X\n"
485 " BIOS segment: %05X\n"
486 " Interrupt: %u\n"
487 " DMA channel: %u\n"
488 " H/A SCSI ID: %u\n"
489 " Subversion: %u\n",
490 config.port_address, config.bios_segment, config.interrupt,
491 config.dma_channel, config.ha_scsi_id, config.subversion);
492 #endif
493 tpnt->this_id = config.ha_scsi_id;
494 tpnt->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, 0, "Ultrastor")) {
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,"Ultrastor")) {
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 tpnt->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(Scsi_Host_Template * tpnt)
519 {
520 register int i;
521 struct Scsi_Host * shpnt = NULL;
522
523 #if (ULTRASTOR_DEBUG & UD_DETECT)
524 printk("US24F: detect");
525 #endif
526
527
528 for (i = 1; i < 15; i++)
529 {
530 unsigned char config_1, config_2;
531 unsigned short addr = (i << 12) | ULTRASTOR_24F_PORT;
532
533 if (inb(addr) != US24F_PRODUCT_ID_0 &&
534 inb(addr+1) != US24F_PRODUCT_ID_1 &&
535 inb(addr+2) != US24F_PRODUCT_ID_2)
536 continue;
537
538 config.revision = inb(addr+3);
539 config.slot = i;
540 if (! (inb(addr+4) & 1))
541 {
542 #if (ULTRASTOR_DEBUG & UD_DETECT)
543 printk("U24F: found disabled card in slot %u\n", i);
544 #endif
545 continue;
546 }
547 #if (ULTRASTOR_DEBUG & UD_DETECT)
548 printk("U24F: found card in slot %u\n", i);
549 #endif
550 config_1 = inb(addr + 5);
551 config.bios_segment = bios_segment_table[config_1 & 7];
552 switch(config_1 >> 4)
553 {
554 case 1:
555 config.interrupt = 15;
556 break;
557 case 2:
558 config.interrupt = 14;
559 break;
560 case 4:
561 config.interrupt = 11;
562 break;
563 case 8:
564 config.interrupt = 10;
565 break;
566 default:
567 printk("U24F: invalid IRQ\n");
568 return FALSE;
569 }
570 if (request_irq(config.interrupt, ultrastor_interrupt, 0, "Ultrastor"))
571 {
572 printk("Unable to allocate IRQ%u for UltraStor controller.\n",
573 config.interrupt);
574 return FALSE;
575 }
576
577
578 config.port_address = addr;
579 config.doorbell_address = addr + 12;
580 config.ogm_address = addr + 0x17;
581 config.icm_address = addr + 0x1C;
582 config_2 = inb(addr + 7);
583 config.ha_scsi_id = config_2 & 7;
584 config.heads = mapping_table[(config_2 >> 3) & 3].heads;
585 config.sectors = mapping_table[(config_2 >> 3) & 3].sectors;
586 #if (ULTRASTOR_DEBUG & UD_DETECT)
587 printk("US24F: detect: detect succeeded\n"
588 " Port address: %03X\n"
589 " BIOS segment: %05X\n"
590 " Interrupt: %u\n"
591 " H/A SCSI ID: %u\n",
592 config.port_address, config.bios_segment,
593 config.interrupt, config.ha_scsi_id);
594 #endif
595 tpnt->this_id = config.ha_scsi_id;
596 tpnt->unchecked_isa_dma = 0;
597 tpnt->sg_tablesize = ULTRASTOR_24F_MAX_SG;
598
599 shpnt = scsi_register(tpnt, 0);
600 shpnt->irq = config.interrupt;
601 shpnt->dma_channel = config.dma_channel;
602 shpnt->io_port = config.port_address;
603
604 #if ULTRASTOR_MAX_CMDS > 1
605 config.mscp_free = ~0;
606 #endif
607
608 outb(0, addr + 0x16);
609 outb(0, addr + 0x1B);
610
611
612
613 outb(ultrastor_bus_reset ? 0xc2 : 0x82, LCL_DOORBELL_MASK(addr+12));
614 outb(0x02, SYS_DOORBELL_MASK(addr+12));
615 printk("UltraStor driver version " VERSION ". Using %d SG lists.\n",
616 tpnt->sg_tablesize);
617 return TRUE;
618 }
619 return FALSE;
620 }
621
622 int ultrastor_detect(Scsi_Host_Template * tpnt)
623 {
624 return ultrastor_14f_detect(tpnt) || ultrastor_24f_detect(tpnt);
625 }
626
627 const char *ultrastor_info(struct Scsi_Host * shpnt)
628 {
629 static char buf[64];
630
631 if (config.slot)
632 sprintf(buf, "UltraStor 24F SCSI @ Slot %u IRQ%u\n",
633 config.slot, config.interrupt);
634 else if (config.subversion)
635 sprintf(buf, "UltraStor 34F SCSI @ Port %03X BIOS %05X IRQ%u\n",
636 config.port_address, (int)config.bios_segment,
637 config.interrupt);
638 else
639 sprintf(buf, "UltraStor 14F SCSI @ Port %03X BIOS %05X IRQ%u DMA%u\n",
640 config.port_address, (int)config.bios_segment,
641 config.interrupt, config.dma_channel);
642 return buf;
643 }
644
645 static inline void build_sg_list(register struct mscp *mscp, Scsi_Cmnd *SCpnt)
646 {
647 struct scatterlist *sl;
648 long transfer_length = 0;
649 int i, max;
650
651 sl = (struct scatterlist *) SCpnt->request_buffer;
652 max = SCpnt->use_sg;
653 for (i = 0; i < max; i++) {
654 mscp->sglist[i].address = (unsigned int)sl[i].address;
655 mscp->sglist[i].num_bytes = sl[i].length;
656 transfer_length += sl[i].length;
657 }
658 mscp->number_of_sg_list = max;
659 mscp->transfer_data = (unsigned int)mscp->sglist;
660
661
662
663 mscp->transfer_data_length = transfer_length;
664 }
665
666 int ultrastor_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
667 {
668 register struct mscp *my_mscp;
669 #if ULTRASTOR_MAX_CMDS > 1
670 int mscp_index;
671 #endif
672 unsigned int status;
673 int flags;
674
675
676 if ((config.mscp_free & ((1U << ULTRASTOR_MAX_CMDS) - 1)) == 0)
677 panic("ultrastor_queuecommand: no free MSCP\n");
678 mscp_index = find_and_clear_bit_16(&config.mscp_free);
679
680
681 if (xchgb(0xff, &config.aborted[mscp_index]) != 0)
682 {
683 status = DID_ABORT << 16;
684 goto aborted;
685 }
686
687 my_mscp = &config.mscp[mscp_index];
688
689 #if 1
690
691 *(unsigned char *)my_mscp = OP_SCSI | (DTD_SCSI << 3);
692 #else
693 my_mscp->opcode = OP_SCSI;
694 my_mscp->xdir = DTD_SCSI;
695 my_mscp->dcn = FALSE;
696 #endif
697
698
699
700
701
702
703
704 my_mscp->ca = SCpnt->device->type != TYPE_TAPE;
705 my_mscp->target_id = SCpnt->target;
706 my_mscp->ch_no = 0;
707 my_mscp->lun = SCpnt->lun;
708 if (SCpnt->use_sg) {
709
710 my_mscp->sg = TRUE;
711 build_sg_list(my_mscp, SCpnt);
712 } else {
713
714 my_mscp->sg = FALSE;
715 my_mscp->transfer_data = (unsigned int)SCpnt->request_buffer;
716 my_mscp->transfer_data_length = SCpnt->request_bufflen;
717 }
718 my_mscp->command_link = 0;
719 my_mscp->scsi_command_link_id = 0;
720 my_mscp->length_of_sense_byte = sizeof SCpnt->sense_buffer;
721 my_mscp->length_of_scsi_cdbs = SCpnt->cmd_len;
722 memcpy(my_mscp->scsi_cdbs, SCpnt->cmnd, my_mscp->length_of_scsi_cdbs);
723 my_mscp->adapter_status = 0;
724 my_mscp->target_status = 0;
725 my_mscp->sense_data = (unsigned int)&SCpnt->sense_buffer;
726 my_mscp->done = done;
727 my_mscp->SCint = SCpnt;
728 SCpnt->host_scribble = (unsigned char *)my_mscp;
729
730
731
732
733 retry:
734 if (config.slot)
735 while (inb(config.ogm_address - 1) != 0 &&
736 config.aborted[mscp_index] == 0xff);
737
738
739
740 while ((inb(LCL_DOORBELL_INTR(config.doorbell_address)) &
741 (config.slot ? 2 : 1))
742 && config.aborted[mscp_index] == 0xff);
743
744
745
746
747 save_flags(flags);
748 cli();
749
750 if (inb(LCL_DOORBELL_INTR(config.doorbell_address)) &
751 (config.slot ? 2 : 1))
752 {
753 restore_flags(flags);
754 goto retry;
755 }
756
757 status = xchgb(0, &config.aborted[mscp_index]);
758 if (status != 0xff) {
759 restore_flags(flags);
760
761 #if ULTRASTOR_DEBUG & (UD_COMMAND | UD_ABORT)
762 printk("USx4F: queuecommand: aborted\n");
763 #if ULTRASTOR_MAX_CMDS > 1
764 log_ultrastor_abort(&config, mscp_index);
765 #endif
766 #endif
767 status <<= 16;
768
769 aborted:
770 set_bit(mscp_index, &config.mscp_free);
771
772
773 #if ULTRASTOR_MAX_CMDS > 1
774 SCpnt->result = status;
775 done(SCpnt);
776 return 0;
777 #else
778 return status;
779 #endif
780 }
781
782
783 outl((unsigned int)my_mscp, config.ogm_address);
784
785
786 if (config.slot) {
787
788 outb(1, config.ogm_address - 1);
789 outb(0x2, LCL_DOORBELL_INTR(config.doorbell_address));
790 } else {
791 outb(0x1, LCL_DOORBELL_INTR(config.doorbell_address));
792 }
793
794 restore_flags(flags);
795
796 #if (ULTRASTOR_DEBUG & UD_COMMAND)
797 printk("USx4F: queuecommand: returning\n");
798 #endif
799
800 return 0;
801 }
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818 int ultrastor_abort(Scsi_Cmnd *SCpnt)
819 {
820 #if ULTRASTOR_DEBUG & UD_ABORT
821 char out[108];
822 unsigned char icm_status = 0, ogm_status = 0;
823 unsigned int icm_addr = 0, ogm_addr = 0;
824 #endif
825 unsigned int mscp_index;
826 unsigned char old_aborted;
827 void (*done)(Scsi_Cmnd *);
828
829 if(config.slot)
830 return SCSI_ABORT_SNOOZE;
831
832
833 if(!SCpnt->host_scribble)
834 return SCSI_ABORT_NOT_RUNNING;
835
836 mscp_index = ((struct mscp *)SCpnt->host_scribble) - config.mscp;
837 if (mscp_index >= ULTRASTOR_MAX_CMDS)
838 panic("Ux4F aborting invalid MSCP");
839
840 #if ULTRASTOR_DEBUG & UD_ABORT
841 if (config.slot)
842 {
843 int port0 = (config.slot << 12) | 0xc80;
844 int i;
845 int flags;
846 save_flags(flags);
847 cli();
848 strcpy(out, "OGM %d:%x ICM %d:%x ports: ");
849 for (i = 0; i < 16; i++)
850 {
851 unsigned char p = inb(port0 + i);
852 out[28 + i * 3] = "0123456789abcdef"[p >> 4];
853 out[29 + i * 3] = "0123456789abcdef"[p & 15];
854 out[30 + i * 3] = ' ';
855 }
856 out[28 + i * 3] = '\n';
857 out[29 + i * 3] = 0;
858 ogm_status = inb(port0 + 22);
859 ogm_addr = inl(port0 + 23);
860 icm_status = inb(port0 + 27);
861 icm_addr = inl(port0 + 28);
862 restore_flags(flags);
863 }
864
865
866
867
868 if (config.slot ? inb(config.icm_address - 1) == 2 :
869 (inb(SYS_DOORBELL_INTR(config.doorbell_address)) & 1))
870 {
871 int flags;
872 save_flags(flags);
873 printk("Ux4F: abort while completed command pending\n");
874 restore_flags(flags);
875 cli();
876 ultrastor_interrupt(0, NULL);
877 restore_flags(flags);
878 return SCSI_ABORT_SUCCESS;
879 }
880 #endif
881
882 old_aborted = xchgb(DID_ABORT, &config.aborted[mscp_index]);
883
884
885
886 if (old_aborted == 0xff)
887 return SCSI_ABORT_SUCCESS;
888
889
890
891 if (config.slot && inb(config.ogm_address - 1) == 0)
892 {
893 int flags;
894
895 save_flags(flags);
896 cli();
897 outl((int)&config.mscp[mscp_index], config.ogm_address);
898 inb(0xc80);
899 outb(0x80, config.ogm_address - 1);
900 outb(0x2, LCL_DOORBELL_INTR(config.doorbell_address));
901 #if ULTRASTOR_DEBUG & UD_ABORT
902 log_ultrastor_abort(&config, mscp_index);
903 printk(out, ogm_status, ogm_addr, icm_status, icm_addr);
904 #endif
905 restore_flags(flags);
906 return SCSI_ABORT_PENDING;
907 }
908
909 #if ULTRASTOR_DEBUG & UD_ABORT
910 log_ultrastor_abort(&config, mscp_index);
911 #endif
912
913
914
915
916
917
918
919
920
921
922
923 #if ULTRASTOR_DEBUG & UD_ABORT
924 if (config.mscp[mscp_index].SCint != SCpnt)
925 printk("abort: command mismatch, %p != %p\n",
926 config.mscp[mscp_index].SCint, SCpnt);
927 #endif
928 if (config.mscp[mscp_index].SCint == 0)
929 return SCSI_ABORT_NOT_RUNNING;
930
931 if (config.mscp[mscp_index].SCint != SCpnt) panic("Bad abort");
932 config.mscp[mscp_index].SCint = 0;
933 done = config.mscp[mscp_index].done;
934 config.mscp[mscp_index].done = 0;
935 SCpnt->result = DID_ABORT << 16;
936
937 done(SCpnt);
938
939
940 return SCSI_ABORT_SUCCESS;
941 }
942
943 int ultrastor_reset(Scsi_Cmnd * SCpnt)
944 {
945 int flags;
946 register int i;
947 #if (ULTRASTOR_DEBUG & UD_RESET)
948 printk("US14F: reset: called\n");
949 #endif
950
951 if(config.slot)
952 return SCSI_RESET_PUNT;
953
954 save_flags(flags);
955 cli();
956
957
958
959 outb(0xc0, LCL_DOORBELL_INTR(config.doorbell_address));
960 if (config.slot)
961 {
962 outb(0, config.ogm_address - 1);
963 outb(0, config.icm_address - 1);
964 }
965
966 #if ULTRASTOR_MAX_CMDS == 1
967 if (config.mscp_busy && config.mscp->done && config.mscp->SCint)
968 {
969 config.mscp->SCint->result = DID_RESET << 16;
970 config.mscp->done(config.mscp->SCint);
971 }
972 config.mscp->SCint = 0;
973 #else
974 for (i = 0; i < ULTRASTOR_MAX_CMDS; i++)
975 {
976 if (! (config.mscp_free & (1 << i)) &&
977 config.mscp[i].done && config.mscp[i].SCint)
978 {
979 config.mscp[i].SCint->result = DID_RESET << 16;
980 config.mscp[i].done(config.mscp[i].SCint);
981 config.mscp[i].done = 0;
982 }
983 config.mscp[i].SCint = 0;
984 }
985 #endif
986
987
988
989
990 memset((unsigned char *)config.aborted, 0, sizeof config.aborted);
991 #if ULTRASTOR_MAX_CMDS == 1
992 config.mscp_busy = 0;
993 #else
994 config.mscp_free = ~0;
995 #endif
996
997 restore_flags(flags);
998 return SCSI_RESET_SUCCESS;
999
1000 }
1001
1002 int ultrastor_biosparam(Disk * disk, int dev, int * dkinfo)
1003 {
1004 int size = disk->capacity;
1005 unsigned int s = config.heads * config.sectors;
1006
1007 dkinfo[0] = config.heads;
1008 dkinfo[1] = config.sectors;
1009 dkinfo[2] = size / s;
1010 #if 0
1011 if (dkinfo[2] > 1024)
1012 dkinfo[2] = 1024;
1013 #endif
1014 return 0;
1015 }
1016
1017 static void ultrastor_interrupt(int irq, struct pt_regs *regs)
1018 {
1019 unsigned int status;
1020 #if ULTRASTOR_MAX_CMDS > 1
1021 unsigned int mscp_index;
1022 #endif
1023 register struct mscp *mscp;
1024 void (*done)(Scsi_Cmnd *);
1025 Scsi_Cmnd *SCtmp;
1026
1027 #if ULTRASTOR_MAX_CMDS == 1
1028 mscp = &config.mscp[0];
1029 #else
1030 mscp = (struct mscp *)inl(config.icm_address);
1031 mscp_index = mscp - config.mscp;
1032 if (mscp_index >= ULTRASTOR_MAX_CMDS) {
1033 printk("Ux4F interrupt: bad MSCP address %x\n", (unsigned int) mscp);
1034
1035
1036 ultrastor_reset(NULL);
1037 return;
1038 }
1039 #endif
1040
1041
1042 if (config.slot) {
1043 unsigned char icm_status = inb(config.icm_address - 1);
1044 #if ULTRASTOR_DEBUG & (UD_INTERRUPT|UD_ERROR|UD_ABORT)
1045 if (icm_status != 1 && icm_status != 2)
1046 printk("US24F: ICM status %x for MSCP %d (%x)\n", icm_status,
1047 mscp_index, (unsigned int) mscp);
1048 #endif
1049
1050
1051 outb(2, SYS_DOORBELL_INTR(config.doorbell_address));
1052 outb(0, config.icm_address - 1);
1053 if (icm_status == 4) {
1054 printk("UltraStor abort command failed\n");
1055 return;
1056 }
1057 if (icm_status == 3) {
1058 void (*done)(Scsi_Cmnd *) = mscp->done;
1059 if (done) {
1060 mscp->done = 0;
1061 mscp->SCint->result = DID_ABORT << 16;
1062 done(mscp->SCint);
1063 }
1064 return;
1065 }
1066 } else {
1067 outb(1, SYS_DOORBELL_INTR(config.doorbell_address));
1068 }
1069
1070 SCtmp = mscp->SCint;
1071 mscp->SCint = NULL;
1072
1073 if (SCtmp == 0)
1074 {
1075 #if ULTRASTOR_DEBUG & (UD_ABORT|UD_INTERRUPT)
1076 printk("MSCP %d (%x): no command\n", mscp_index, (unsigned int) mscp);
1077 #endif
1078 #if ULTRASTOR_MAX_CMDS == 1
1079 config.mscp_busy = FALSE;
1080 #else
1081 set_bit(mscp_index, &config.mscp_free);
1082 #endif
1083 config.aborted[mscp_index] = 0;
1084 return;
1085 }
1086
1087
1088
1089
1090 done = mscp->done;
1091 mscp->done = 0;
1092
1093
1094 switch (mscp->adapter_status)
1095 {
1096 case 0:
1097 status = DID_OK << 16;
1098 break;
1099 case 0x01:
1100 case 0x02:
1101 case 0x03:
1102 default:
1103 status = DID_ERROR << 16;
1104 break;
1105 case 0x84:
1106 status = DID_ABORT << 16;
1107 break;
1108 case 0x91:
1109 status = DID_TIME_OUT << 16;
1110 break;
1111 }
1112
1113 SCtmp->result = status | mscp->target_status;
1114
1115 SCtmp->host_scribble = 0;
1116
1117
1118 #if ULTRASTOR_MAX_CMDS == 1
1119 config.mscp_busy = FALSE;
1120 #else
1121 set_bit(mscp_index, &config.mscp_free);
1122 #endif
1123
1124 #if ULTRASTOR_DEBUG & (UD_ABORT|UD_INTERRUPT)
1125 if (config.aborted[mscp_index])
1126 printk("Ux4 interrupt: MSCP %d (%x) aborted = %d\n",
1127 mscp_index, (unsigned int) mscp, config.aborted[mscp_index]);
1128 #endif
1129 config.aborted[mscp_index] = 0;
1130
1131 if (done)
1132 done(SCtmp);
1133 else
1134 printk("US14F: interrupt: unexpected interrupt\n");
1135
1136 if (config.slot ? inb(config.icm_address - 1) : (inb(SYS_DOORBELL_INTR(config.doorbell_address)) & 1))
1137 printk("Ux4F: multiple commands completed\n");
1138
1139 #if (ULTRASTOR_DEBUG & UD_INTERRUPT)
1140 printk("USx4F: interrupt: returning\n");
1141 #endif
1142 }