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
128
129
130#include <linux/module.h>
131#include <linux/blkdev.h>
132#include <linux/interrupt.h>
133#include <linux/stddef.h>
134#include <linux/string.h>
135#include <linux/kernel.h>
136#include <linux/ioport.h>
137#include <linux/proc_fs.h>
138#include <linux/spinlock.h>
139#include <linux/stat.h>
140#include <linux/bitops.h>
141
142#include <asm/io.h>
143#include <asm/system.h>
144#include <asm/dma.h>
145
146#define ULTRASTOR_PRIVATE
147#include "scsi.h"
148#include <scsi/scsi_host.h>
149#include "ultrastor.h"
150
151#define FALSE 0
152#define TRUE 1
153
154#ifndef ULTRASTOR_DEBUG
155#define ULTRASTOR_DEBUG (UD_ABORT|UD_CSIR|UD_RESET)
156#endif
157
158#define VERSION "1.12"
159
160#define PACKED __attribute__((packed))
161#define ALIGNED(x) __attribute__((aligned(x)))
162
163
164
165
166
167
168
169typedef struct {
170 u32 address;
171 u32 num_bytes;
172} ultrastor_sg_list;
173
174
175
176
177struct 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 u32 sense_data PACKED;
197
198
199 void (*done) (struct scsi_cmnd *);
200 struct 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
225static 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 long mscp_free;
256#endif
257 volatile unsigned char aborted[ULTRASTOR_MAX_CMDS];
258 struct mscp mscp[ULTRASTOR_MAX_CMDS];
259} config = {0};
260
261
262static int ultrastor_bus_reset;
263
264
265
266static 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
272static const unsigned char interrupt_table_14f[4] = { 15, 14, 11, 10 };
273
274
275static const unsigned char dma_channel_table_14f[4] = { 5, 6, 7, 0 };
276
277
278static 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
285static const unsigned short ultrastor_ports_14f[] = {
286 0x330, 0x340, 0x230, 0x240, 0x210, 0x130, 0x140,
287};
288#endif
289
290static void ultrastor_interrupt(void *);
291static irqreturn_t do_ultrastor_interrupt(int, void *);
292static inline void build_sg_list(struct mscp *, struct scsi_cmnd *SCpnt);
293
294
295
296
297static inline int find_and_clear_bit_16(unsigned long *field)
298{
299 int rv;
300
301 if (*field == 0)
302 panic("No free mscp");
303
304 asm volatile (
305 "xorl %0,%0\n\t"
306 "0: bsfw %1,%w0\n\t"
307 "btr %0,%1\n\t"
308 "jnc 0b"
309 : "=&r" (rv), "=m" (*field) :);
310
311 return rv;
312}
313
314
315
316
317
318
319
320
321
322static 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
332static void log_ultrastor_abort(struct ultrastor_config *config,
333 int command)
334{
335 static char fmt[80] = "abort %d (%x); MSCP free pool: %x;";
336 int i;
337
338 for (i = 0; i < ULTRASTOR_MAX_CMDS; i++)
339 {
340 fmt[20 + i*2] = ' ';
341 if (! (config->mscp_free & (1 << i)))
342 fmt[21 + i*2] = '0' + config->mscp[i].target_id;
343 else
344 fmt[21 + i*2] = '-';
345 }
346 fmt[20 + ULTRASTOR_MAX_CMDS * 2] = '\n';
347 fmt[21 + ULTRASTOR_MAX_CMDS * 2] = 0;
348 printk(fmt, command, &config->mscp[command], config->mscp_free);
349
350}
351#endif
352
353static int ultrastor_14f_detect(struct scsi_host_template * tpnt)
354{
355 size_t i;
356 unsigned char in_byte, version_byte = 0;
357 struct config_1 {
358 unsigned char bios_segment: 3;
359 unsigned char removable_disks_as_fixed: 1;
360 unsigned char interrupt: 2;
361 unsigned char dma_channel: 2;
362 } config_1;
363 struct config_2 {
364 unsigned char ha_scsi_id: 3;
365 unsigned char mapping_mode: 2;
366 unsigned char bios_drive_number: 1;
367 unsigned char tfr_port: 2;
368 } config_2;
369
370#if (ULTRASTOR_DEBUG & UD_DETECT)
371 printk("US14F: detect: called\n");
372#endif
373
374
375 if (config.bios_segment)
376 return FALSE;
377
378#ifdef PORT_OVERRIDE
379 if(!request_region(PORT_OVERRIDE, 0xc, "ultrastor")) {
380 printk("Ultrastor I/O space already in use\n");
381 return FALSE;
382 };
383 config.port_address = PORT_OVERRIDE;
384#else
385 for (i = 0; i < ARRAY_SIZE(ultrastor_ports_14f); i++) {
386 if(!request_region(ultrastor_ports_14f[i], 0x0c, "ultrastor")) continue;
387 config.port_address = ultrastor_ports_14f[i];
388#endif
389
390#if (ULTRASTOR_DEBUG & UD_DETECT)
391 printk("US14F: detect: testing port address %03X\n", config.port_address);
392#endif
393
394 in_byte = inb(U14F_PRODUCT_ID(config.port_address));
395 if (in_byte != US14F_PRODUCT_ID_0) {
396#if (ULTRASTOR_DEBUG & UD_DETECT)
397# ifdef PORT_OVERRIDE
398 printk("US14F: detect: wrong product ID 0 - %02X\n", in_byte);
399# else
400 printk("US14F: detect: no adapter at port %03X\n", config.port_address);
401# endif
402#endif
403#ifdef PORT_OVERRIDE
404 goto out_release_port;
405#else
406 release_region(config.port_address, 0x0c);
407 continue;
408#endif
409 }
410 in_byte = inb(U14F_PRODUCT_ID(config.port_address) + 1);
411
412 if ((in_byte & 0xF0) != US14F_PRODUCT_ID_1) {
413#if (ULTRASTOR_DEBUG & UD_DETECT)
414# ifdef PORT_OVERRIDE
415 printk("US14F: detect: wrong product ID 1 - %02X\n", in_byte);
416# else
417 printk("US14F: detect: no adapter at port %03X\n", config.port_address);
418# endif
419#endif
420#ifdef PORT_OVERRIDE
421 goto out_release_port;
422#else
423 release_region(config.port_address, 0x0c);
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
436 return FALSE;
437 }
438#endif
439
440#if (ULTRASTOR_DEBUG & UD_DETECT)
441 printk("US14F: detect: adapter found at port address %03X\n",
442 config.port_address);
443#endif
444
445
446
447 outb(ultrastor_bus_reset ? 0xc2 : 0x82, LCL_DOORBELL_MASK(config.port_address));
448
449
450
451
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 goto out_release_port;
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 goto out_release_port;
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
511
512
513
514 if (request_irq(config.interrupt, do_ultrastor_interrupt, 0, "Ultrastor", &config.mscp[0].SCint->device->host)) {
515 printk("Unable to allocate IRQ%u for UltraStor controller.\n",
516 config.interrupt);
517 goto out_release_port;
518 }
519 if (config.dma_channel && request_dma(config.dma_channel,"Ultrastor")) {
520 printk("Unable to allocate DMA channel %u for UltraStor controller.\n",
521 config.dma_channel);
522 free_irq(config.interrupt, NULL);
523 goto out_release_port;
524 }
525 tpnt->sg_tablesize = ULTRASTOR_14F_MAX_SG;
526 printk("UltraStor driver version" VERSION ". Using %d SG lists.\n",
527 ULTRASTOR_14F_MAX_SG);
528
529 return TRUE;
530out_release_port:
531 release_region(config.port_address, 0x0c);
532 return FALSE;
533}
534
535static int ultrastor_24f_detect(struct scsi_host_template * tpnt)
536{
537 int i;
538 struct Scsi_Host * shpnt = NULL;
539
540#if (ULTRASTOR_DEBUG & UD_DETECT)
541 printk("US24F: detect");
542#endif
543
544
545 for (i = 1; i < 15; i++)
546 {
547 unsigned char config_1, config_2;
548 unsigned short addr = (i << 12) | ULTRASTOR_24F_PORT;
549
550 if (inb(addr) != US24F_PRODUCT_ID_0 &&
551 inb(addr+1) != US24F_PRODUCT_ID_1 &&
552 inb(addr+2) != US24F_PRODUCT_ID_2)
553 continue;
554
555 config.revision = inb(addr+3);
556 config.slot = i;
557 if (! (inb(addr+4) & 1))
558 {
559#if (ULTRASTOR_DEBUG & UD_DETECT)
560 printk("U24F: found disabled card in slot %u\n", i);
561#endif
562 continue;
563 }
564#if (ULTRASTOR_DEBUG & UD_DETECT)
565 printk("U24F: found card in slot %u\n", i);
566#endif
567 config_1 = inb(addr + 5);
568 config.bios_segment = bios_segment_table[config_1 & 7];
569 switch(config_1 >> 4)
570 {
571 case 1:
572 config.interrupt = 15;
573 break;
574 case 2:
575 config.interrupt = 14;
576 break;
577 case 4:
578 config.interrupt = 11;
579 break;
580 case 8:
581 config.interrupt = 10;
582 break;
583 default:
584 printk("U24F: invalid IRQ\n");
585 return FALSE;
586 }
587
588
589
590 config.port_address = addr;
591 config.doorbell_address = addr + 12;
592 config.ogm_address = addr + 0x17;
593 config.icm_address = addr + 0x1C;
594 config_2 = inb(addr + 7);
595 config.ha_scsi_id = config_2 & 7;
596 config.heads = mapping_table[(config_2 >> 3) & 3].heads;
597 config.sectors = mapping_table[(config_2 >> 3) & 3].sectors;
598#if (ULTRASTOR_DEBUG & UD_DETECT)
599 printk("US24F: detect: detect succeeded\n"
600 " Port address: %03X\n"
601 " BIOS segment: %05X\n"
602 " Interrupt: %u\n"
603 " H/A SCSI ID: %u\n",
604 config.port_address, config.bios_segment,
605 config.interrupt, config.ha_scsi_id);
606#endif
607 tpnt->this_id = config.ha_scsi_id;
608 tpnt->unchecked_isa_dma = 0;
609 tpnt->sg_tablesize = ULTRASTOR_24F_MAX_SG;
610
611 shpnt = scsi_register(tpnt, 0);
612 if (!shpnt) {
613 printk(KERN_WARNING "(ultrastor:) Could not register scsi device. Aborting registration.\n");
614 free_irq(config.interrupt, do_ultrastor_interrupt);
615 return FALSE;
616 }
617
618 if (request_irq(config.interrupt, do_ultrastor_interrupt, 0, "Ultrastor", shpnt))
619 {
620 printk("Unable to allocate IRQ%u for UltraStor controller.\n",
621 config.interrupt);
622 return FALSE;
623 }
624
625 shpnt->irq = config.interrupt;
626 shpnt->dma_channel = config.dma_channel;
627 shpnt->io_port = config.port_address;
628
629#if ULTRASTOR_MAX_CMDS > 1
630 config.mscp_free = ~0;
631#endif
632
633 outb(0, addr + 0x16);
634 outb(0, addr + 0x1B);
635
636
637
638 outb(ultrastor_bus_reset ? 0xc2 : 0x82, LCL_DOORBELL_MASK(addr+12));
639 outb(0x02, SYS_DOORBELL_MASK(addr+12));
640 printk("UltraStor driver version " VERSION ". Using %d SG lists.\n",
641 tpnt->sg_tablesize);
642 return TRUE;
643 }
644 return FALSE;
645}
646
647static int ultrastor_detect(struct scsi_host_template * tpnt)
648{
649 tpnt->proc_name = "ultrastor";
650 return ultrastor_14f_detect(tpnt) || ultrastor_24f_detect(tpnt);
651}
652
653static int ultrastor_release(struct Scsi_Host *shost)
654{
655 if (shost->irq)
656 free_irq(shost->irq, NULL);
657 if (shost->dma_channel != 0xff)
658 free_dma(shost->dma_channel);
659 if (shost->io_port && shost->n_io_port)
660 release_region(shost->io_port, shost->n_io_port);
661 scsi_unregister(shost);
662 return 0;
663}
664
665static const char *ultrastor_info(struct Scsi_Host * shpnt)
666{
667 static char buf[64];
668
669 if (config.slot)
670 sprintf(buf, "UltraStor 24F SCSI @ Slot %u IRQ%u",
671 config.slot, config.interrupt);
672 else if (config.subversion)
673 sprintf(buf, "UltraStor 34F SCSI @ Port %03X BIOS %05X IRQ%u",
674 config.port_address, (int)config.bios_segment,
675 config.interrupt);
676 else
677 sprintf(buf, "UltraStor 14F SCSI @ Port %03X BIOS %05X IRQ%u DMA%u",
678 config.port_address, (int)config.bios_segment,
679 config.interrupt, config.dma_channel);
680 return buf;
681}
682
683static inline void build_sg_list(struct mscp *mscp, struct scsi_cmnd *SCpnt)
684{
685 struct scatterlist *sg;
686 long transfer_length = 0;
687 int i, max;
688
689 max = scsi_sg_count(SCpnt);
690 scsi_for_each_sg(SCpnt, sg, max, i) {
691 mscp->sglist[i].address = isa_page_to_bus(sg_page(sg)) + sg->offset;
692 mscp->sglist[i].num_bytes = sg->length;
693 transfer_length += sg->length;
694 }
695 mscp->number_of_sg_list = max;
696 mscp->transfer_data = isa_virt_to_bus(mscp->sglist);
697
698
699
700 mscp->transfer_data_length = transfer_length;
701}
702
703static int ultrastor_queuecommand(struct scsi_cmnd *SCpnt,
704 void (*done) (struct scsi_cmnd *))
705{
706 struct mscp *my_mscp;
707#if ULTRASTOR_MAX_CMDS > 1
708 int mscp_index;
709#endif
710 unsigned int status;
711
712
713 if ((config.mscp_free & ((1U << ULTRASTOR_MAX_CMDS) - 1)) == 0)
714 panic("ultrastor_queuecommand: no free MSCP\n");
715 mscp_index = find_and_clear_bit_16(&config.mscp_free);
716
717
718 if (xchgb(0xff, &config.aborted[mscp_index]) != 0)
719 {
720 status = DID_ABORT << 16;
721 goto aborted;
722 }
723
724 my_mscp = &config.mscp[mscp_index];
725
726 *(unsigned char *)my_mscp = OP_SCSI | (DTD_SCSI << 3);
727
728
729
730
731
732
733
734
735 my_mscp->ca = SCpnt->device->type != TYPE_TAPE;
736 my_mscp->target_id = SCpnt->device->id;
737 my_mscp->ch_no = 0;
738 my_mscp->lun = SCpnt->device->lun;
739 if (scsi_sg_count(SCpnt)) {
740
741 my_mscp->sg = TRUE;
742 build_sg_list(my_mscp, SCpnt);
743 } else {
744
745 my_mscp->sg = FALSE;
746 my_mscp->transfer_data = isa_virt_to_bus(scsi_sglist(SCpnt));
747 my_mscp->transfer_data_length = scsi_bufflen(SCpnt);
748 }
749 my_mscp->command_link = 0;
750 my_mscp->scsi_command_link_id = 0;
751 my_mscp->length_of_sense_byte = SCSI_SENSE_BUFFERSIZE;
752 my_mscp->length_of_scsi_cdbs = SCpnt->cmd_len;
753 memcpy(my_mscp->scsi_cdbs, SCpnt->cmnd, my_mscp->length_of_scsi_cdbs);
754 my_mscp->adapter_status = 0;
755 my_mscp->target_status = 0;
756 my_mscp->sense_data = isa_virt_to_bus(&SCpnt->sense_buffer);
757 my_mscp->done = done;
758 my_mscp->SCint = SCpnt;
759 SCpnt->host_scribble = (unsigned char *)my_mscp;
760
761
762
763
764
765
766
767retry:
768 if (config.slot)
769 while (inb(config.ogm_address - 1) != 0 && config.aborted[mscp_index] == 0xff)
770 barrier();
771
772
773
774 while ((inb(LCL_DOORBELL_INTR(config.doorbell_address)) & (config.slot ? 2 : 1)) && config.aborted[mscp_index] == 0xff)
775 barrier();
776
777
778
779
780
781
782 if (inb(LCL_DOORBELL_INTR(config.doorbell_address)) & (config.slot ? 2 : 1))
783 goto retry;
784
785 status = xchgb(0, &config.aborted[mscp_index]);
786 if (status != 0xff) {
787
788#if ULTRASTOR_DEBUG & (UD_COMMAND | UD_ABORT)
789 printk("USx4F: queuecommand: aborted\n");
790#if ULTRASTOR_MAX_CMDS > 1
791 log_ultrastor_abort(&config, mscp_index);
792#endif
793#endif
794 status <<= 16;
795
796 aborted:
797 set_bit(mscp_index, &config.mscp_free);
798
799
800#if ULTRASTOR_MAX_CMDS > 1
801 SCpnt->result = status;
802 done(SCpnt);
803 return 0;
804#else
805 return status;
806#endif
807 }
808
809
810 outl(isa_virt_to_bus(my_mscp), config.ogm_address);
811
812
813 if (config.slot) {
814
815 outb(1, config.ogm_address - 1);
816 outb(0x2, LCL_DOORBELL_INTR(config.doorbell_address));
817 } else {
818 outb(0x1, LCL_DOORBELL_INTR(config.doorbell_address));
819 }
820
821#if (ULTRASTOR_DEBUG & UD_COMMAND)
822 printk("USx4F: queuecommand: returning\n");
823#endif
824
825 return 0;
826}
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843static int ultrastor_abort(struct scsi_cmnd *SCpnt)
844{
845#if ULTRASTOR_DEBUG & UD_ABORT
846 char out[108];
847 unsigned char icm_status = 0, ogm_status = 0;
848 unsigned int icm_addr = 0, ogm_addr = 0;
849#endif
850 unsigned int mscp_index;
851 unsigned char old_aborted;
852 unsigned long flags;
853 void (*done)(struct scsi_cmnd *);
854 struct Scsi_Host *host = SCpnt->device->host;
855
856 if(config.slot)
857 return FAILED;
858
859
860 if(!SCpnt->host_scribble)
861 return FAILED;
862
863 mscp_index = ((struct mscp *)SCpnt->host_scribble) - config.mscp;
864 if (mscp_index >= ULTRASTOR_MAX_CMDS)
865 panic("Ux4F aborting invalid MSCP");
866
867#if ULTRASTOR_DEBUG & UD_ABORT
868 if (config.slot)
869 {
870 int port0 = (config.slot << 12) | 0xc80;
871 int i;
872 unsigned long flags;
873
874 spin_lock_irqsave(host->host_lock, flags);
875 strcpy(out, "OGM %d:%x ICM %d:%x ports: ");
876 for (i = 0; i < 16; i++)
877 {
878 unsigned char p = inb(port0 + i);
879 out[28 + i * 3] = "0123456789abcdef"[p >> 4];
880 out[29 + i * 3] = "0123456789abcdef"[p & 15];
881 out[30 + i * 3] = ' ';
882 }
883 out[28 + i * 3] = '\n';
884 out[29 + i * 3] = 0;
885 ogm_status = inb(port0 + 22);
886 ogm_addr = (unsigned int)isa_bus_to_virt(inl(port0 + 23));
887 icm_status = inb(port0 + 27);
888 icm_addr = (unsigned int)isa_bus_to_virt(inl(port0 + 28));
889 spin_unlock_irqrestore(host->host_lock, flags);
890 }
891
892
893
894
895 if (config.slot ? inb(config.icm_address - 1) == 2 :
896 (inb(SYS_DOORBELL_INTR(config.doorbell_address)) & 1))
897 {
898 printk("Ux4F: abort while completed command pending\n");
899
900 spin_lock_irqsave(host->host_lock, flags);
901
902 ultrastor_interrupt(NULL);
903 spin_unlock_irqrestore(host->host_lock, flags);
904 return SUCCESS;
905 }
906#endif
907
908 old_aborted = xchgb(DID_ABORT, &config.aborted[mscp_index]);
909
910
911
912 if (old_aborted == 0xff)
913 return SUCCESS;
914
915
916
917 if (config.slot && inb(config.ogm_address - 1) == 0)
918 {
919 unsigned long flags;
920
921 spin_lock_irqsave(host->host_lock, flags);
922 outl(isa_virt_to_bus(&config.mscp[mscp_index]), config.ogm_address);
923 udelay(8);
924 outb(0x80, config.ogm_address - 1);
925 outb(0x2, LCL_DOORBELL_INTR(config.doorbell_address));
926#if ULTRASTOR_DEBUG & UD_ABORT
927 log_ultrastor_abort(&config, mscp_index);
928 printk(out, ogm_status, ogm_addr, icm_status, icm_addr);
929#endif
930 spin_unlock_irqrestore(host->host_lock, flags);
931
932 return SUCCESS;
933 }
934
935#if ULTRASTOR_DEBUG & UD_ABORT
936 log_ultrastor_abort(&config, mscp_index);
937#endif
938
939
940
941
942
943
944
945
946
947
948
949#if ULTRASTOR_DEBUG & UD_ABORT
950 if (config.mscp[mscp_index].SCint != SCpnt)
951 printk("abort: command mismatch, %p != %p\n",
952 config.mscp[mscp_index].SCint, SCpnt);
953#endif
954 if (config.mscp[mscp_index].SCint == NULL)
955 return FAILED;
956
957 if (config.mscp[mscp_index].SCint != SCpnt) panic("Bad abort");
958 config.mscp[mscp_index].SCint = NULL;
959 done = config.mscp[mscp_index].done;
960 config.mscp[mscp_index].done = NULL;
961 SCpnt->result = DID_ABORT << 16;
962
963
964 done(SCpnt);
965
966
967 return SUCCESS;
968}
969
970static int ultrastor_host_reset(struct scsi_cmnd * SCpnt)
971{
972 unsigned long flags;
973 int i;
974 struct Scsi_Host *host = SCpnt->device->host;
975
976#if (ULTRASTOR_DEBUG & UD_RESET)
977 printk("US14F: reset: called\n");
978#endif
979
980 if(config.slot)
981 return FAILED;
982
983 spin_lock_irqsave(host->host_lock, flags);
984
985
986 outb(0xc0, LCL_DOORBELL_INTR(config.doorbell_address));
987 if (config.slot)
988 {
989 outb(0, config.ogm_address - 1);
990 outb(0, config.icm_address - 1);
991 }
992
993#if ULTRASTOR_MAX_CMDS == 1
994 if (config.mscp_busy && config.mscp->done && config.mscp->SCint)
995 {
996 config.mscp->SCint->result = DID_RESET << 16;
997 config.mscp->done(config.mscp->SCint);
998 }
999 config.mscp->SCint = 0;
1000#else
1001 for (i = 0; i < ULTRASTOR_MAX_CMDS; i++)
1002 {
1003 if (! (config.mscp_free & (1 << i)) &&
1004 config.mscp[i].done && config.mscp[i].SCint)
1005 {
1006 config.mscp[i].SCint->result = DID_RESET << 16;
1007 config.mscp[i].done(config.mscp[i].SCint);
1008 config.mscp[i].done = NULL;
1009 }
1010 config.mscp[i].SCint = NULL;
1011 }
1012#endif
1013
1014
1015
1016
1017
1018
1019
1020 memset((unsigned char *)config.aborted, 0, sizeof config.aborted);
1021#if ULTRASTOR_MAX_CMDS == 1
1022 config.mscp_busy = 0;
1023#else
1024 config.mscp_free = ~0;
1025#endif
1026
1027 spin_unlock_irqrestore(host->host_lock, flags);
1028 return SUCCESS;
1029
1030}
1031
1032int ultrastor_biosparam(struct scsi_device *sdev, struct block_device *bdev,
1033 sector_t capacity, int * dkinfo)
1034{
1035 int size = capacity;
1036 unsigned int s = config.heads * config.sectors;
1037
1038 dkinfo[0] = config.heads;
1039 dkinfo[1] = config.sectors;
1040 dkinfo[2] = size / s;
1041#if 0
1042 if (dkinfo[2] > 1024)
1043 dkinfo[2] = 1024;
1044#endif
1045 return 0;
1046}
1047
1048static void ultrastor_interrupt(void *dev_id)
1049{
1050 unsigned int status;
1051#if ULTRASTOR_MAX_CMDS > 1
1052 unsigned int mscp_index;
1053#endif
1054 struct mscp *mscp;
1055 void (*done) (struct scsi_cmnd *);
1056 struct scsi_cmnd *SCtmp;
1057
1058#if ULTRASTOR_MAX_CMDS == 1
1059 mscp = &config.mscp[0];
1060#else
1061 mscp = (struct mscp *)isa_bus_to_virt(inl(config.icm_address));
1062 mscp_index = mscp - config.mscp;
1063 if (mscp_index >= ULTRASTOR_MAX_CMDS) {
1064 printk("Ux4F interrupt: bad MSCP address %x\n", (unsigned int) mscp);
1065
1066
1067 ultrastor_host_reset(dev_id);
1068 return;
1069 }
1070#endif
1071
1072
1073 if (config.slot) {
1074 unsigned char icm_status = inb(config.icm_address - 1);
1075#if ULTRASTOR_DEBUG & (UD_INTERRUPT|UD_ERROR|UD_ABORT)
1076 if (icm_status != 1 && icm_status != 2)
1077 printk("US24F: ICM status %x for MSCP %d (%x)\n", icm_status,
1078 mscp_index, (unsigned int) mscp);
1079#endif
1080
1081
1082 outb(2, SYS_DOORBELL_INTR(config.doorbell_address));
1083 outb(0, config.icm_address - 1);
1084 if (icm_status == 4) {
1085 printk("UltraStor abort command failed\n");
1086 return;
1087 }
1088 if (icm_status == 3) {
1089 void (*done)(struct scsi_cmnd *) = mscp->done;
1090 if (done) {
1091 mscp->done = NULL;
1092 mscp->SCint->result = DID_ABORT << 16;
1093 done(mscp->SCint);
1094 }
1095 return;
1096 }
1097 } else {
1098 outb(1, SYS_DOORBELL_INTR(config.doorbell_address));
1099 }
1100
1101 SCtmp = mscp->SCint;
1102 mscp->SCint = NULL;
1103
1104 if (!SCtmp)
1105 {
1106#if ULTRASTOR_DEBUG & (UD_ABORT|UD_INTERRUPT)
1107 printk("MSCP %d (%x): no command\n", mscp_index, (unsigned int) mscp);
1108#endif
1109#if ULTRASTOR_MAX_CMDS == 1
1110 config.mscp_busy = FALSE;
1111#else
1112 set_bit(mscp_index, &config.mscp_free);
1113#endif
1114 config.aborted[mscp_index] = 0;
1115 return;
1116 }
1117
1118
1119
1120
1121 done = mscp->done;
1122 mscp->done = NULL;
1123
1124
1125 switch (mscp->adapter_status)
1126 {
1127 case 0:
1128 status = DID_OK << 16;
1129 break;
1130 case 0x01:
1131 case 0x02:
1132 case 0x03:
1133 default:
1134 status = DID_ERROR << 16;
1135 break;
1136 case 0x84:
1137 status = DID_ABORT << 16;
1138 break;
1139 case 0x91:
1140 status = DID_TIME_OUT << 16;
1141 break;
1142 }
1143
1144 SCtmp->result = status | mscp->target_status;
1145
1146 SCtmp->host_scribble = NULL;
1147
1148
1149#if ULTRASTOR_MAX_CMDS == 1
1150 config.mscp_busy = FALSE;
1151#else
1152 set_bit(mscp_index, &config.mscp_free);
1153#endif
1154
1155#if ULTRASTOR_DEBUG & (UD_ABORT|UD_INTERRUPT)
1156 if (config.aborted[mscp_index])
1157 printk("Ux4 interrupt: MSCP %d (%x) aborted = %d\n",
1158 mscp_index, (unsigned int) mscp, config.aborted[mscp_index]);
1159#endif
1160 config.aborted[mscp_index] = 0;
1161
1162 if (done)
1163 done(SCtmp);
1164 else
1165 printk("US14F: interrupt: unexpected interrupt\n");
1166
1167 if (config.slot ? inb(config.icm_address - 1) :
1168 (inb(SYS_DOORBELL_INTR(config.doorbell_address)) & 1))
1169#if (ULTRASTOR_DEBUG & UD_MULTI_CMD)
1170 printk("Ux4F: multiple commands completed\n");
1171#else
1172 ;
1173#endif
1174
1175#if (ULTRASTOR_DEBUG & UD_INTERRUPT)
1176 printk("USx4F: interrupt: returning\n");
1177#endif
1178}
1179
1180static irqreturn_t do_ultrastor_interrupt(int irq, void *dev_id)
1181{
1182 unsigned long flags;
1183 struct Scsi_Host *dev = dev_id;
1184
1185 spin_lock_irqsave(dev->host_lock, flags);
1186 ultrastor_interrupt(dev_id);
1187 spin_unlock_irqrestore(dev->host_lock, flags);
1188 return IRQ_HANDLED;
1189}
1190
1191MODULE_LICENSE("GPL");
1192
1193static struct scsi_host_template driver_template = {
1194 .name = "UltraStor 14F/24F/34F",
1195 .detect = ultrastor_detect,
1196 .release = ultrastor_release,
1197 .info = ultrastor_info,
1198 .queuecommand = ultrastor_queuecommand,
1199 .eh_abort_handler = ultrastor_abort,
1200 .eh_host_reset_handler = ultrastor_host_reset,
1201 .bios_param = ultrastor_biosparam,
1202 .can_queue = ULTRASTOR_MAX_CMDS,
1203 .sg_tablesize = ULTRASTOR_14F_MAX_SG,
1204 .cmd_per_lun = ULTRASTOR_MAX_CMDS_PER_LUN,
1205 .unchecked_isa_dma = 1,
1206 .use_clustering = ENABLE_CLUSTERING,
1207};
1208#include "scsi_module.c"
1209