269 #include <linux/module.h>
274 #include <linux/errno.h>
275 #include <linux/string.h>
278 #include <linux/pci.h>
279 #include <linux/stat.h>
282 #include <linux/slab.h>
286 #include <scsi/scsi.h>
300 #define VERSION "$Revision: 5.51 $"
305 #define ENABLE_PARITY 1
311 #define EVERY_ACCESS 0
312 #define ERRORS_ONLY 1
313 #define DEBUG_DETECT 0
314 #define DEBUG_MESSAGES 1
315 #define DEBUG_ABORT 1
316 #define DEBUG_RESET 1
319 #define EVERY_ACCESS 0
320 #define ERRORS_ONLY 0
321 #define DEBUG_DETECT 0
322 #define DEBUG_MESSAGES 0
323 #define DEBUG_ABORT 0
324 #define DEBUG_RESET 0
331 #define ERRORS_ONLY 0
335 #define PARITY_MASK 0x08
337 #define PARITY_MASK 0x00
386 static int port_base;
387 static unsigned long bios_base;
388 static void __iomem * bios_mem;
393 static struct pci_dev *PCI_dev;
396 static int interrupt_level;
397 static volatile int in_command;
400 static int adapter_mask;
402 static int setup_called;
405 static volatile int in_interrupt_flag;
408 static int FIFO_Size = 0x2000;
414 static char * fdomain =
NULL;
419 static unsigned long addresses[] = {
428 #define ADDRESS_COUNT ARRAY_SIZE(addresses)
430 static unsigned short ports[] = { 0x140, 0x150, 0x160, 0x170 };
431 #define PORT_COUNT ARRAY_SIZE(ports)
433 static unsigned short ints[] = { 3, 5, 10, 11, 12, 14, 15, 0 };
475 int major_bios_version;
476 int minor_bios_version;
481 {
"FUTURE DOMAIN CORP. (C) 1986-1990 1800-V2.07/28/89", 5, 50, 2, 0, 0 },
482 {
"FUTURE DOMAIN CORP. (C) 1986-1990 1800-V1.07/28/89", 5, 50, 2, 0, 0 },
483 {
"FUTURE DOMAIN CORP. (C) 1986-1990 1800-V2.07/28/89", 72, 50, 2, 0, 2 },
484 {
"FUTURE DOMAIN CORP. (C) 1986-1990 1800-V2.0", 73, 43, 2, 0, 3 },
485 {
"FUTURE DOMAIN CORP. (C) 1991 1800-V2.0.", 72, 39, 2, 0, 4 },
486 {
"FUTURE DOMAIN CORP. (C) 1992 V3.00.004/02/92", 5, 44, 3, 0, 0 },
487 {
"FUTURE DOMAIN TMC-18XX (C) 1993 V3.203/12/93", 5, 44, 3, 2, 0 },
488 {
"IBM F1 P2 BIOS v1.0104/29/93", 5, 28, 3, -1, 0 },
489 {
"Future Domain Corp. V1.0008/18/93", 5, 33, 3, 4, 0 },
490 {
"Future Domain Corp. V1.0008/18/93", 26, 33, 3, 4, 1 },
491 {
"Adaptec AHA-2920 PCI-SCSI Card", 42, 31, 3, -1, 1 },
492 {
"IBM F1 P264/32", 5, 14, 3, -1, 1 },
494 {
"Future Domain Corp. V2.0108/18/93", 5, 33, 3, 5, 0 },
495 {
"FUTURE DOMAIN CORP. V3.5008/18/93", 5, 34, 3, 5, 0 },
496 {
"FUTURE DOMAIN 18c30/18c50/1800 (C) 1994 V3.5", 5, 44, 3, 5, 0 },
497 {
"FUTURE DOMAIN CORP. V3.6008/18/93", 5, 34, 3, 6, 0 },
498 {
"FUTURE DOMAIN CORP. V3.6108/18/93", 5, 34, 3, 6, 0 },
499 {
"FUTURE DOMAIN TMC-18XX", 5, 22, -1, -1, 0 },
514 #define SIGNATURE_COUNT ARRAY_SIZE(signatures)
518 static void print_banner(
struct Scsi_Host *shpnt )
534 printk(
" at 0x%lx using scsi id %d\n",
548 printk(
"%d", interrupt_level);
561 if (setup_called++ || ints[0] < 2 || ints[0] > 3) {
562 printk(
KERN_INFO "scsi: <fdomain> Usage: fdomain=<PORT_BASE>,<IRQ>[,<ADAPTER_ID>]\n");
567 port_base = ints[0] >= 1 ? ints[1] : 0;
568 interrupt_level = ints[0] >= 2 ? ints[2] : 0;
569 this_id = ints[0] >= 3 ? ints[3] : 0;
579 static void do_pause(
unsigned amount)
584 static inline void fdomain_make_bus_idle(
void )
594 static int fdomain_is_valid_port(
int port )
634 static int fdomain_test_loopback(
void )
639 for (i = 0; i < 255; i++) {
664 static int fdomain_get_irq(
int base )
669 printk(
"scsi: <fdomain> Options = %x\n", options);
677 if (
chip !=
tmc18c30 && !PCI_bus && addresses[(options & 0xc0) >> 6 ] != bios_base)
679 return ints[(options & 0x0e) >> 1];
682 static int fdomain_isa_detect(
int *irq,
int *
iobase )
685 int base = 0xdeadbeef;
689 printk(
"scsi: <fdomain> fdomain_isa_detect:" );
697 printk(
" %lx(%lx),", addresses[i], bios_base );
702 signatures[j].sig_length )) {
705 PCI_bus = (signatures[
j].flag == 1);
706 Quantum = (signatures[
j].flag > 1) ? signatures[j].flag : 0;
707 bios_base = addresses[
i];
728 base =
readb(bios_mem + 0x1fa2) + (
readb(bios_mem + 0x1fa3) << 8);
731 base =
readb(bios_mem + 0x1fa3) + (
readb(bios_mem + 0x1fa4) << 8);
734 base =
readb(bios_mem + 0x1fcc) + (
readb(bios_mem + 0x1fcd) << 8);
743 if (base == ports[i]) {
746 if (!fdomain_is_valid_port(base)) {
750 *irq = fdomain_get_irq( base );
761 printk(
" RAM FAILED, " );
778 printk(
" (%x inuse),", base );
785 flag = fdomain_is_valid_port(base);
792 if (flag)
printk(
" SUCCESS\n" );
793 else printk(
" FAILURE\n" );
798 *irq = fdomain_get_irq( base );
806 static int fdomain_isa_detect(
int *irq,
int *iobase )
823 static int fdomain_pci_bios_detect(
int *irq,
int *iobase,
struct pci_dev **ret_pdev )
825 unsigned int pci_irq;
826 unsigned long pci_base;
833 printk(
"scsi: <fdomain> INFO: use lspci -v to see list of PCI devices\n" );
834 printk(
"scsi: <fdomain> TMC-3260 detect:"
835 " Using Vendor ID: 0x%x and Device ID: 0x%x\n",
846 printk(
"scsi: <fdomain> TMC-3260 detect:"
847 " PCI bus %u, device %u, function %u\n",
870 printk(
"scsi: <fdomain> TMC-3260 detect:"
871 " IRQ = %d, I/O base = 0x%x [0x%lx]\n", *irq, *iobase, pci_base );
874 if (!fdomain_is_valid_port(pci_base)) {
875 printk(
KERN_ERR "scsi: <fdomain> PCI card detected, but driver not loaded (invalid port)\n" );
903 printk(
"scsi: <fdomain> No BIOS, using port_base = 0x%x, irq = %d\n",
904 port_base, interrupt_level );
907 printk(
"scsi: <fdomain> port 0x%x is busy\n", port_base );
908 printk(
"scsi: <fdomain> Bad LILO/INSMOD parameters?\n" );
911 if (!fdomain_is_valid_port( port_base )) {
912 printk(
"scsi: <fdomain> Cannot locate chip at port base 0x%x\n",
914 printk(
"scsi: <fdomain> Bad LILO/INSMOD parameters?\n" );
923 flag = fdomain_pci_bios_detect( &interrupt_level, &port_base, &pdev );
927 flag = fdomain_isa_detect( &interrupt_level, &port_base );
930 printk(
"scsi: <fdomain> Detection failed (no card)\n" );
938 if (fdomain_test_loopback()) {
939 printk(
KERN_ERR "scsi: <fdomain> Detection failed (loopback test failed at port base 0x%x)\n", port_base);
947 tpnt->
this_id = (this_id & 0x07);
948 adapter_mask = (1 << tpnt->
this_id);
967 shpnt->
irq = interrupt_level;
970 print_banner( shpnt );
973 if (!interrupt_level) {
974 printk(
KERN_ERR "scsi: <fdomain> Card Detected, but driver not loaded (no IRQ)\n" );
980 do_fdomain_16x0_intr, pdev?
IRQF_SHARED:0,
"fdomain", shpnt);
984 printk(
KERN_ERR "scsi: <fdomain> IRQ %d is bad!\n", interrupt_level );
987 }
else if (retcode == -
EBUSY) {
988 printk(
KERN_ERR "scsi: <fdomain> IRQ %d is already in use!\n", interrupt_level );
991 printk(
KERN_ERR "scsi: <fdomain> Error getting IRQ %d\n", interrupt_level );
995 printk(
KERN_ERR "scsi: <fdomain> Detected, but driver not loaded (IRQ)\n" );
1013 static const char *fdomain_16x0_info(
struct Scsi_Host *ignore )
1018 strcpy( buffer,
"Future Domain 16-bit SCSI Driver Version" );
1021 pt =
strrchr( buffer,
'$') - 1;
1023 pt = buffer +
strlen( buffer ) - 1;
1035 static int fdomain_arbitrate(
void )
1041 printk(
"fdomain_arbitrate()\n" );
1054 }
while (--timeout);
1057 fdomain_make_bus_idle();
1060 printk(
"Arbitration failed, status = %x\n", status );
1063 printk(
"scsi: <fdomain> Arbitration failed, status = %x\n", status );
1069 static int fdomain_select(
int target )
1072 unsigned long timeout;
1074 static int flag = 0;
1093 }
while (--timeout);
1095 fdomain_make_bus_idle();
1097 if (!target)
printk(
"Selection failed\n" );
1104 printk(
"scsi: <fdomain> Selection failed\n" );
1110 static void my_done(
int error)
1115 fdomain_make_bus_idle();
1119 else panic(
"scsi: <fdomain> current_SC->scsi_done() == NULL" );
1121 panic(
"scsi: <fdomain> my_done() called outside of command\n" );
1124 in_interrupt_flag = 0;
1130 unsigned long flags;
1149 if (!in_command || !current_SC) {
1151 printk(
"Spurious interrupt, in_command = %d, current_SC = %x\n",
1152 in_command, current_SC );
1160 printk(
"scsi: <fdomain> Interrupt after abort, ignoring\n" );
1167 ++in_interrupt_flag;
1172 if (!(status & 0x02)) {
1178 spin_unlock_irqrestore(current_SC->
device->host->host_lock, flags);
1191 in_interrupt_flag = 0;
1196 if (!(status & 0x01)) {
1198 if (fdomain_select(
scmd_id(current_SC) )) {
1204 spin_unlock_irqrestore(current_SC->
device->host->host_lock, flags);
1218 in_interrupt_flag = 0;
1227 if (status & 0x10) {
1229 switch (status & 0x0e) {
1232 outb(current_SC->
cmnd[current_SC->
SCp.sent_command++],
1236 current_SC->
cmnd[ current_SC->
SCp.sent_command - 1] );
1241 current_SC->
SCp.have_data_in = -1;
1247 current_SC->
SCp.have_data_in = 1;
1254 printk(
"Status = %x, ", current_SC->
SCp.Status );
1257 if (current_SC->
SCp.Status
1258 && current_SC->
SCp.Status != 2
1259 && current_SC->
SCp.Status != 8) {
1260 printk(
"scsi: <fdomain> target = %d, command = %x, status = %x\n",
1262 current_SC->
cmnd[0],
1263 current_SC->
SCp.Status );
1273 printk(
"Message = %x, ", current_SC->
SCp.Message );
1275 if (!current_SC->
SCp.Message) ++
done;
1276 #if DEBUG_MESSAGES || EVERY_ACCESS
1277 if (current_SC->
SCp.Message) {
1278 printk(
"scsi: <fdomain> message = %x\n",
1279 current_SC->
SCp.Message );
1287 && (current_SC->
SCp.sent_command >= current_SC->
cmd_len)) {
1291 current_SC->
SCp.have_data_in = -1;
1296 current_SC->
SCp.have_data_in = 1;
1301 if (current_SC->
SCp.have_data_in == -1) {
1304 printk(
"DC=%d, ", data_count ) ;
1306 if (data_count > current_SC->
SCp.this_residual)
1307 data_count = current_SC->
SCp.this_residual;
1308 if (data_count > 0) {
1310 printk(
"%d OUT, ", data_count );
1312 if (data_count == 1) {
1314 --current_SC->
SCp.this_residual;
1322 if (!current_SC->
SCp.this_residual) {
1323 if (current_SC->
SCp.buffers_residual) {
1324 --current_SC->
SCp.buffers_residual;
1325 ++current_SC->
SCp.buffer;
1326 current_SC->
SCp.ptr = sg_virt(current_SC->
SCp.buffer);
1327 current_SC->
SCp.this_residual = current_SC->
SCp.buffer->length;
1334 if (current_SC->
SCp.have_data_in == 1) {
1337 printk(
"DC=%d, ", data_count );
1339 if (data_count > current_SC->
SCp.this_residual)
1340 data_count = current_SC->
SCp.this_residual;
1343 printk(
"%d IN, ", data_count );
1345 if (data_count == 1) {
1347 --current_SC->
SCp.this_residual;
1355 if (!current_SC->
SCp.this_residual
1356 && current_SC->
SCp.buffers_residual) {
1357 --current_SC->
SCp.buffers_residual;
1358 ++current_SC->
SCp.buffer;
1359 current_SC->
SCp.ptr = sg_virt(current_SC->
SCp.buffer);
1360 current_SC->
SCp.this_residual = current_SC->
SCp.buffer->length;
1367 printk(
" ** IN DONE %d ** ", current_SC->
SCp.have_data_in );
1372 char *
buf = scsi_sglist(current_SC);
1373 if ((
unsigned char)(*(buf + 2)) & 0x0f) {
1376 unsigned char qualifier;
1378 key = (
unsigned char)(*(buf + 2)) & 0x0f;
1379 code = (
unsigned char)(*(buf + 12));
1380 qualifier = (
unsigned char)(*(buf + 13));
1385 && (!qualifier || qualifier == 0x02 || qualifier == 0x01))
1390 printk(
"scsi: <fdomain> REQUEST SENSE"
1391 " Key = %x, Code = %x, Qualifier = %x\n",
1392 key, code, qualifier );
1397 printk(
"BEFORE MY_DONE. . ." );
1400 my_done( (current_SC->
SCp.Status & 0xff)
1401 | ((current_SC->
SCp.Message & 0xff) << 8) | (
DID_OK << 16) );
1402 spin_unlock_irqrestore(current_SC->
device->host->host_lock, flags);
1404 printk(
"RETURNING.\n" );
1416 in_interrupt_flag = 0;
1421 static int fdomain_16x0_queue_lck(
struct scsi_cmnd *SCpnt,
1425 panic(
"scsi: <fdomain> fdomain_16x0_queue() NOT REENTRANT!\n" );
1428 printk(
"queue: target = %d cmnd = 0x%02x pieces = %d size = %u\n",
1430 *(
unsigned char *)SCpnt->
cmnd,
1431 scsi_sg_count(SCpnt),
1432 scsi_bufflen(SCpnt));
1435 fdomain_make_bus_idle();
1442 if (scsi_sg_count(current_SC)) {
1443 current_SC->
SCp.buffer = scsi_sglist(current_SC);
1444 current_SC->
SCp.ptr = sg_virt(current_SC->
SCp.buffer);
1445 current_SC->
SCp.this_residual = current_SC->
SCp.buffer->length;
1446 current_SC->
SCp.buffers_residual = scsi_sg_count(current_SC) - 1;
1449 current_SC->
SCp.this_residual = 0;
1450 current_SC->
SCp.buffer =
NULL;
1451 current_SC->
SCp.buffers_residual = 0;
1454 current_SC->
SCp.Status = 0;
1455 current_SC->
SCp.Message = 0;
1456 current_SC->
SCp.have_data_in = 0;
1457 current_SC->
SCp.sent_command = 0;
1480 if (!SCpnt || !SCpnt->
device || !SCpnt->
device->host) {
1486 print_banner(SCpnt->
device->host);
1487 switch (SCpnt->
SCp.phase) {
1491 default:
printk(
"unknown");
break;
1494 printk(
" (%d), target = %d cmnd = 0x%02x pieces = %d size = %u\n",
1497 *(
unsigned char *)SCpnt->
cmnd,
1498 scsi_sg_count(SCpnt),
1499 scsi_bufflen(SCpnt));
1500 printk(
"sent_command = %d, have_data_in = %d, timeout = %d\n",
1501 SCpnt->
SCp.sent_command,
1502 SCpnt->
SCp.have_data_in,
1505 printk(
"in_interrupt_flag = %d\n", in_interrupt_flag );
1508 imr = (
inb( 0x0a1 ) << 8) +
inb( 0x21 );
1510 irr =
inb( 0xa0 ) << 8;
1514 isr =
inb( 0xa0 ) << 8;
1519 printk(
"IMR = 0x%04x", imr );
1520 if (imr & (1 << interrupt_level))
1522 printk(
", IRR = 0x%04x, ISR = 0x%04x\n", irr, isr );
1527 printk(
" (interrupt)" );
1535 printk(
"Int. Condition = 0x%02x\n",
1540 printk(
"Configuration 2 = 0x%02x\n",
1545 static int fdomain_16x0_abort(
struct scsi_cmnd *SCpnt)
1547 #if EVERY_ACCESS || ERRORS_ONLY || DEBUG_ABORT
1548 printk(
"scsi: <fdomain> abort " );
1552 #if EVERY_ACCESS || ERRORS_ONLY
1553 printk(
" (not in command)\n" );
1562 fdomain_make_bus_idle();
1573 unsigned long flags;
1588 static int fdomain_16x0_biosparam(
struct scsi_device *sdev,
1597 unsigned char heads;
1645 printk(
"scsi: <fdomain> fdomain_16x0_biosparam: too many disks");
1655 offset = 0x1f33 + drive * 25;
1658 offset = 0x1f36 + drive * 15;
1661 offset = 0x1f34 + drive * 15;
1664 offset = 0x1f31 + drive * 25;
1667 memcpy_fromio( &i, bios_mem + offset,
sizeof(
struct drive_info ) );
1668 info_array[0] = i.heads;
1669 info_array[1] = i.sectors;
1670 info_array[2] = i.cylinders;
1675 sizeof(
struct drive_info ) );
1676 info_array[0] = i.heads + 1;
1677 info_array[1] = i.sectors;
1678 info_array[2] = i.cylinders;
1683 if (p && p[65] == 0xaa && p[64] == 0x55
1715 info_array[0] = p[5] + 1;
1716 info_array[1] = p[6] & 0x3f;
1723 if ((
unsigned int)size >= 0x7e0000U) {
1724 info_array[0] = 0xff;
1725 info_array[1] = 0x3f;
1726 }
else if ((
unsigned int)size >= 0x200000U) {
1727 info_array[0] = 0x80;
1728 info_array[1] = 0x3f;
1730 info_array[0] = 0x40;
1731 info_array[1] = 0x20;
1735 info_array[2] = (
unsigned int)size / (info_array[0] * info_array[1] );
1742 static int fdomain_16x0_release(
struct Scsi_Host *shpnt)
1756 .proc_name =
"fdomain",
1757 .detect = fdomain_16x0_detect,
1758 .info = fdomain_16x0_info,
1759 .queuecommand = fdomain_16x0_queue,
1760 .eh_abort_handler = fdomain_16x0_abort,
1762 .bios_param = fdomain_16x0_biosparam,
1763 .release = fdomain_16x0_release,
1781 #define driver_template fdomain_driver_template