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