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#include <linux/delay.h>
142
143#include <asm/io.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_lck(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
828static DEF_SCSI_QCMD(ultrastor_queuecommand)
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845static int ultrastor_abort(struct scsi_cmnd *SCpnt)
846{
847#if ULTRASTOR_DEBUG & UD_ABORT
848 char out[108];
849 unsigned char icm_status = 0, ogm_status = 0;
850 unsigned int icm_addr = 0, ogm_addr = 0;
851#endif
852 unsigned int mscp_index;
853 unsigned char old_aborted;
854 unsigned long flags;
855 void (*done)(struct scsi_cmnd *);
856 struct Scsi_Host *host = SCpnt->device->host;
857
858 if(config.slot)
859 return FAILED;
860
861
862 if(!SCpnt->host_scribble)
863 return FAILED;
864
865 mscp_index = ((struct mscp *)SCpnt->host_scribble) - config.mscp;
866 if (mscp_index >= ULTRASTOR_MAX_CMDS)
867 panic("Ux4F aborting invalid MSCP");
868
869#if ULTRASTOR_DEBUG & UD_ABORT
870 if (config.slot)
871 {
872 int port0 = (config.slot << 12) | 0xc80;
873 int i;
874 unsigned long flags;
875
876 spin_lock_irqsave(host->host_lock, flags);
877 strcpy(out, "OGM %d:%x ICM %d:%x ports: ");
878 for (i = 0; i < 16; i++)
879 {
880 unsigned char p = inb(port0 + i);
881 out[28 + i * 3] = "0123456789abcdef"[p >> 4];
882 out[29 + i * 3] = "0123456789abcdef"[p & 15];
883 out[30 + i * 3] = ' ';
884 }
885 out[28 + i * 3] = '\n';
886 out[29 + i * 3] = 0;
887 ogm_status = inb(port0 + 22);
888 ogm_addr = (unsigned int)isa_bus_to_virt(inl(port0 + 23));
889 icm_status = inb(port0 + 27);
890 icm_addr = (unsigned int)isa_bus_to_virt(inl(port0 + 28));
891 spin_unlock_irqrestore(host->host_lock, flags);
892 }
893
894
895
896
897 if (config.slot ? inb(config.icm_address - 1) == 2 :
898 (inb(SYS_DOORBELL_INTR(config.doorbell_address)) & 1))
899 {
900 printk("Ux4F: abort while completed command pending\n");
901
902 spin_lock_irqsave(host->host_lock, flags);
903
904 ultrastor_interrupt(NULL);
905 spin_unlock_irqrestore(host->host_lock, flags);
906 return SUCCESS;
907 }
908#endif
909
910 old_aborted = xchgb(DID_ABORT, &config.aborted[mscp_index]);
911
912
913
914 if (old_aborted == 0xff)
915 return SUCCESS;
916
917
918
919 if (config.slot && inb(config.ogm_address - 1) == 0)
920 {
921 unsigned long flags;
922
923 spin_lock_irqsave(host->host_lock, flags);
924 outl(isa_virt_to_bus(&config.mscp[mscp_index]), config.ogm_address);
925 udelay(8);
926 outb(0x80, config.ogm_address - 1);
927 outb(0x2, LCL_DOORBELL_INTR(config.doorbell_address));
928#if ULTRASTOR_DEBUG & UD_ABORT
929 log_ultrastor_abort(&config, mscp_index);
930 printk(out, ogm_status, ogm_addr, icm_status, icm_addr);
931#endif
932 spin_unlock_irqrestore(host->host_lock, flags);
933
934 return SUCCESS;
935 }
936
937#if ULTRASTOR_DEBUG & UD_ABORT
938 log_ultrastor_abort(&config, mscp_index);
939#endif
940
941
942
943
944
945
946
947
948
949
950
951#if ULTRASTOR_DEBUG & UD_ABORT
952 if (config.mscp[mscp_index].SCint != SCpnt)
953 printk("abort: command mismatch, %p != %p\n",
954 config.mscp[mscp_index].SCint, SCpnt);
955#endif
956 if (config.mscp[mscp_index].SCint == NULL)
957 return FAILED;
958
959 if (config.mscp[mscp_index].SCint != SCpnt) panic("Bad abort");
960 config.mscp[mscp_index].SCint = NULL;
961 done = config.mscp[mscp_index].done;
962 config.mscp[mscp_index].done = NULL;
963 SCpnt->result = DID_ABORT << 16;
964
965
966 done(SCpnt);
967
968
969 return SUCCESS;
970}
971
972static int ultrastor_host_reset(struct scsi_cmnd * SCpnt)
973{
974 unsigned long flags;
975 int i;
976 struct Scsi_Host *host = SCpnt->device->host;
977
978#if (ULTRASTOR_DEBUG & UD_RESET)
979 printk("US14F: reset: called\n");
980#endif
981
982 if(config.slot)
983 return FAILED;
984
985 spin_lock_irqsave(host->host_lock, flags);
986
987
988 outb(0xc0, LCL_DOORBELL_INTR(config.doorbell_address));
989 if (config.slot)
990 {
991 outb(0, config.ogm_address - 1);
992 outb(0, config.icm_address - 1);
993 }
994
995#if ULTRASTOR_MAX_CMDS == 1
996 if (config.mscp_busy && config.mscp->done && config.mscp->SCint)
997 {
998 config.mscp->SCint->result = DID_RESET << 16;
999 config.mscp->done(config.mscp->SCint);
1000 }
1001 config.mscp->SCint = 0;
1002#else
1003 for (i = 0; i < ULTRASTOR_MAX_CMDS; i++)
1004 {
1005 if (! (config.mscp_free & (1 << i)) &&
1006 config.mscp[i].done && config.mscp[i].SCint)
1007 {
1008 config.mscp[i].SCint->result = DID_RESET << 16;
1009 config.mscp[i].done(config.mscp[i].SCint);
1010 config.mscp[i].done = NULL;
1011 }
1012 config.mscp[i].SCint = NULL;
1013 }
1014#endif
1015
1016
1017
1018
1019
1020
1021
1022 memset((unsigned char *)config.aborted, 0, sizeof config.aborted);
1023#if ULTRASTOR_MAX_CMDS == 1
1024 config.mscp_busy = 0;
1025#else
1026 config.mscp_free = ~0;
1027#endif
1028
1029 spin_unlock_irqrestore(host->host_lock, flags);
1030 return SUCCESS;
1031
1032}
1033
1034int ultrastor_biosparam(struct scsi_device *sdev, struct block_device *bdev,
1035 sector_t capacity, int * dkinfo)
1036{
1037 int size = capacity;
1038 unsigned int s = config.heads * config.sectors;
1039
1040 dkinfo[0] = config.heads;
1041 dkinfo[1] = config.sectors;
1042 dkinfo[2] = size / s;
1043#if 0
1044 if (dkinfo[2] > 1024)
1045 dkinfo[2] = 1024;
1046#endif
1047 return 0;
1048}
1049
1050static void ultrastor_interrupt(void *dev_id)
1051{
1052 unsigned int status;
1053#if ULTRASTOR_MAX_CMDS > 1
1054 unsigned int mscp_index;
1055#endif
1056 struct mscp *mscp;
1057 void (*done) (struct scsi_cmnd *);
1058 struct scsi_cmnd *SCtmp;
1059
1060#if ULTRASTOR_MAX_CMDS == 1
1061 mscp = &config.mscp[0];
1062#else
1063 mscp = (struct mscp *)isa_bus_to_virt(inl(config.icm_address));
1064 mscp_index = mscp - config.mscp;
1065 if (mscp_index >= ULTRASTOR_MAX_CMDS) {
1066 printk("Ux4F interrupt: bad MSCP address %x\n", (unsigned int) mscp);
1067
1068
1069 ultrastor_host_reset(dev_id);
1070 return;
1071 }
1072#endif
1073
1074
1075 if (config.slot) {
1076 unsigned char icm_status = inb(config.icm_address - 1);
1077#if ULTRASTOR_DEBUG & (UD_INTERRUPT|UD_ERROR|UD_ABORT)
1078 if (icm_status != 1 && icm_status != 2)
1079 printk("US24F: ICM status %x for MSCP %d (%x)\n", icm_status,
1080 mscp_index, (unsigned int) mscp);
1081#endif
1082
1083
1084 outb(2, SYS_DOORBELL_INTR(config.doorbell_address));
1085 outb(0, config.icm_address - 1);
1086 if (icm_status == 4) {
1087 printk("UltraStor abort command failed\n");
1088 return;
1089 }
1090 if (icm_status == 3) {
1091 void (*done)(struct scsi_cmnd *) = mscp->done;
1092 if (done) {
1093 mscp->done = NULL;
1094 mscp->SCint->result = DID_ABORT << 16;
1095 done(mscp->SCint);
1096 }
1097 return;
1098 }
1099 } else {
1100 outb(1, SYS_DOORBELL_INTR(config.doorbell_address));
1101 }
1102
1103 SCtmp = mscp->SCint;
1104 mscp->SCint = NULL;
1105
1106 if (!SCtmp)
1107 {
1108#if ULTRASTOR_DEBUG & (UD_ABORT|UD_INTERRUPT)
1109 printk("MSCP %d (%x): no command\n", mscp_index, (unsigned int) mscp);
1110#endif
1111#if ULTRASTOR_MAX_CMDS == 1
1112 config.mscp_busy = FALSE;
1113#else
1114 set_bit(mscp_index, &config.mscp_free);
1115#endif
1116 config.aborted[mscp_index] = 0;
1117 return;
1118 }
1119
1120
1121
1122
1123 done = mscp->done;
1124 mscp->done = NULL;
1125
1126
1127 switch (mscp->adapter_status)
1128 {
1129 case 0:
1130 status = DID_OK << 16;
1131 break;
1132 case 0x01:
1133 case 0x02:
1134 case 0x03:
1135 default:
1136 status = DID_ERROR << 16;
1137 break;
1138 case 0x84:
1139 status = DID_ABORT << 16;
1140 break;
1141 case 0x91:
1142 status = DID_TIME_OUT << 16;
1143 break;
1144 }
1145
1146 SCtmp->result = status | mscp->target_status;
1147
1148 SCtmp->host_scribble = NULL;
1149
1150
1151#if ULTRASTOR_MAX_CMDS == 1
1152 config.mscp_busy = FALSE;
1153#else
1154 set_bit(mscp_index, &config.mscp_free);
1155#endif
1156
1157#if ULTRASTOR_DEBUG & (UD_ABORT|UD_INTERRUPT)
1158 if (config.aborted[mscp_index])
1159 printk("Ux4 interrupt: MSCP %d (%x) aborted = %d\n",
1160 mscp_index, (unsigned int) mscp, config.aborted[mscp_index]);
1161#endif
1162 config.aborted[mscp_index] = 0;
1163
1164 if (done)
1165 done(SCtmp);
1166 else
1167 printk("US14F: interrupt: unexpected interrupt\n");
1168
1169 if (config.slot ? inb(config.icm_address - 1) :
1170 (inb(SYS_DOORBELL_INTR(config.doorbell_address)) & 1))
1171#if (ULTRASTOR_DEBUG & UD_MULTI_CMD)
1172 printk("Ux4F: multiple commands completed\n");
1173#else
1174 ;
1175#endif
1176
1177#if (ULTRASTOR_DEBUG & UD_INTERRUPT)
1178 printk("USx4F: interrupt: returning\n");
1179#endif
1180}
1181
1182static irqreturn_t do_ultrastor_interrupt(int irq, void *dev_id)
1183{
1184 unsigned long flags;
1185 struct Scsi_Host *dev = dev_id;
1186
1187 spin_lock_irqsave(dev->host_lock, flags);
1188 ultrastor_interrupt(dev_id);
1189 spin_unlock_irqrestore(dev->host_lock, flags);
1190 return IRQ_HANDLED;
1191}
1192
1193MODULE_LICENSE("GPL");
1194
1195static struct scsi_host_template driver_template = {
1196 .name = "UltraStor 14F/24F/34F",
1197 .detect = ultrastor_detect,
1198 .release = ultrastor_release,
1199 .info = ultrastor_info,
1200 .queuecommand = ultrastor_queuecommand,
1201 .eh_abort_handler = ultrastor_abort,
1202 .eh_host_reset_handler = ultrastor_host_reset,
1203 .bios_param = ultrastor_biosparam,
1204 .can_queue = ULTRASTOR_MAX_CMDS,
1205 .sg_tablesize = ULTRASTOR_14F_MAX_SG,
1206 .cmd_per_lun = ULTRASTOR_MAX_CMDS_PER_LUN,
1207 .unchecked_isa_dma = 1,
1208 .use_clustering = ENABLE_CLUSTERING,
1209};
1210#include "scsi_module.c"
1211