Merge branches 'acpi-resources', 'acpi-battery', 'acpi-doc' and 'acpi-pnp'
[linux-2.6-block.git] / drivers / scsi / aha1542.c
CommitLineData
1d084d20
OZ
1/*
2 * Driver for Adaptec AHA-1542 SCSI host adapters
1da177e4
LT
3 *
4 * Copyright (C) 1992 Tommy Thorn
5 * Copyright (C) 1993, 1994, 1995 Eric Youngdale
1d084d20 6 * Copyright (C) 2015 Ondrej Zary
1da177e4
LT
7 */
8
1da177e4
LT
9#include <linux/module.h>
10#include <linux/interrupt.h>
11#include <linux/kernel.h>
12#include <linux/types.h>
13#include <linux/string.h>
1da177e4 14#include <linux/delay.h>
1da177e4
LT
15#include <linux/init.h>
16#include <linux/spinlock.h>
643a7c43
OZ
17#include <linux/isa.h>
18#include <linux/pnp.h>
5a0e3ad6 19#include <linux/slab.h>
954a9fd7 20#include <linux/io.h>
1da177e4 21#include <asm/dma.h>
954a9fd7
OZ
22#include <scsi/scsi_cmnd.h>
23#include <scsi/scsi_device.h>
1da177e4
LT
24#include <scsi/scsi_host.h>
25#include "aha1542.h"
1da177e4 26
f71429ab 27#define MAXBOARDS 4
1da177e4 28
f71429ab
OZ
29static bool isapnp = 1;
30module_param(isapnp, bool, 0);
31MODULE_PARM_DESC(isapnp, "enable PnP support (default=1)");
1da177e4 32
f71429ab
OZ
33static int io[MAXBOARDS] = { 0x330, 0x334, 0, 0 };
34module_param_array(io, int, NULL, 0);
35MODULE_PARM_DESC(io, "base IO address of controller (0x130,0x134,0x230,0x234,0x330,0x334, default=0x330,0x334)");
1da177e4 36
f71429ab
OZ
37/* time AHA spends on the AT-bus during data transfer */
38static int bus_on[MAXBOARDS] = { -1, -1, -1, -1 }; /* power-on default: 11us */
39module_param_array(bus_on, int, NULL, 0);
40MODULE_PARM_DESC(bus_on, "bus on time [us] (2-15, default=-1 [HW default: 11])");
1da177e4 41
f71429ab
OZ
42/* time AHA spends off the bus (not to monopolize it) during data transfer */
43static int bus_off[MAXBOARDS] = { -1, -1, -1, -1 }; /* power-on default: 4us */
44module_param_array(bus_off, int, NULL, 0);
45MODULE_PARM_DESC(bus_off, "bus off time [us] (1-64, default=-1 [HW default: 4])");
1da177e4 46
f71429ab
OZ
47/* default is jumper selected (J1 on 1542A), factory default = 5 MB/s */
48static int dma_speed[MAXBOARDS] = { -1, -1, -1, -1 };
49module_param_array(dma_speed, int, NULL, 0);
50MODULE_PARM_DESC(dma_speed, "DMA speed [MB/s] (5,6,7,8,10, default=-1 [by jumper])");
1da177e4 51
1da177e4
LT
52#define BIOS_TRANSLATION_6432 1 /* Default case these days */
53#define BIOS_TRANSLATION_25563 2 /* Big disk case */
54
55struct aha1542_hostdata {
56 /* This will effectively start both of them at the first mailbox */
57 int bios_translation; /* Mapping bios uses - for compatibility */
58 int aha1542_last_mbi_used;
59 int aha1542_last_mbo_used;
55b28f9f 60 struct scsi_cmnd *int_cmds[AHA1542_MAILBOXES];
1da177e4
LT
61 struct mailbox mb[2 * AHA1542_MAILBOXES];
62 struct ccb ccb[AHA1542_MAILBOXES];
63};
64
f1bbef63
OZ
65static inline void aha1542_intr_reset(u16 base)
66{
67 outb(IRST, CONTROL(base));
68}
1da177e4 69
2093bfa1
OZ
70static inline bool wait_mask(u16 port, u8 mask, u8 allof, u8 noneof, int timeout)
71{
72 bool delayed = true;
73
74 if (timeout == 0) {
75 timeout = 3000000;
76 delayed = false;
77 }
78
79 while (1) {
80 u8 bits = inb(port) & mask;
81 if ((bits & allof) == allof && ((bits & noneof) == 0))
82 break;
83 if (delayed)
84 mdelay(1);
85 if (--timeout == 0)
86 return false;
87 }
88
89 return true;
90}
1da177e4 91
cad2fc72 92static int aha1542_outb(unsigned int base, u8 val)
1da177e4 93{
eef77801
OZ
94 if (!wait_mask(STATUS(base), CDF, 0, CDF, 0))
95 return 1;
96 outb(val, DATA(base));
97
98 return 0;
0c2b6481
OZ
99}
100
cad2fc72 101static int aha1542_out(unsigned int base, u8 *buf, int len)
0c2b6481 102{
0c2b6481 103 while (len--) {
1b0224b0 104 if (!wait_mask(STATUS(base), CDF, 0, CDF, 0))
0c2b6481 105 return 1;
cad2fc72 106 outb(*buf++, DATA(base));
0c2b6481 107 }
23e6940a
OZ
108 if (!wait_mask(INTRFLAGS(base), INTRMASK, HACC, 0, 0))
109 return 1;
0c2b6481 110
1da177e4 111 return 0;
1da177e4
LT
112}
113
114/* Only used at boot time, so we do not need to worry about latency as much
115 here */
116
cad2fc72 117static int aha1542_in(unsigned int base, u8 *buf, int len, int timeout)
1da177e4 118{
1da177e4 119 while (len--) {
1b0224b0 120 if (!wait_mask(STATUS(base), DF, DF, 0, timeout))
a13b3722 121 return 1;
cad2fc72 122 *buf++ = inb(DATA(base));
1da177e4 123 }
1da177e4 124 return 0;
1da177e4
LT
125}
126
127static int makecode(unsigned hosterr, unsigned scsierr)
128{
129 switch (hosterr) {
130 case 0x0:
131 case 0xa: /* Linked command complete without error and linked normally */
132 case 0xb: /* Linked command complete without error, interrupt generated */
133 hosterr = 0;
134 break;
135
136 case 0x11: /* Selection time out-The initiator selection or target
137 reselection was not complete within the SCSI Time out period */
138 hosterr = DID_TIME_OUT;
139 break;
140
141 case 0x12: /* Data overrun/underrun-The target attempted to transfer more data
142 than was allocated by the Data Length field or the sum of the
143 Scatter / Gather Data Length fields. */
144
145 case 0x13: /* Unexpected bus free-The target dropped the SCSI BSY at an unexpected time. */
146
147 case 0x15: /* MBO command was not 00, 01 or 02-The first byte of the CB was
148 invalid. This usually indicates a software failure. */
149
150 case 0x16: /* Invalid CCB Operation Code-The first byte of the CCB was invalid.
151 This usually indicates a software failure. */
152
153 case 0x17: /* Linked CCB does not have the same LUN-A subsequent CCB of a set
154 of linked CCB's does not specify the same logical unit number as
155 the first. */
156 case 0x18: /* Invalid Target Direction received from Host-The direction of a
157 Target Mode CCB was invalid. */
158
159 case 0x19: /* Duplicate CCB Received in Target Mode-More than once CCB was
160 received to service data transfer between the same target LUN
161 and initiator SCSI ID in the same direction. */
162
163 case 0x1a: /* Invalid CCB or Segment List Parameter-A segment list with a zero
164 length segment or invalid segment list boundaries was received.
165 A CCB parameter was invalid. */
fde1fb8a
OZ
166#ifdef DEBUG
167 printk("Aha1542: %x %x\n", hosterr, scsierr);
168#endif
1da177e4
LT
169 hosterr = DID_ERROR; /* Couldn't find any better */
170 break;
171
172 case 0x14: /* Target bus phase sequence failure-An invalid bus phase or bus
173 phase sequence was requested by the target. The host adapter
174 will generate a SCSI Reset Condition, notifying the host with
175 a SCRD interrupt */
176 hosterr = DID_RESET;
177 break;
178 default:
179 printk(KERN_ERR "aha1542: makecode: unknown hoststatus %x\n", hosterr);
180 break;
181 }
182 return scsierr | (hosterr << 16);
183}
184
68ea9de3 185static int aha1542_test_port(struct Scsi_Host *sh)
1da177e4 186{
cb5b570c 187 u8 inquiry_result[4];
cad2fc72 188 int i;
1da177e4
LT
189
190 /* Quick and dirty test for presence of the card. */
68ea9de3 191 if (inb(STATUS(sh->io_port)) == 0xff)
1da177e4
LT
192 return 0;
193
194 /* Reset the adapter. I ought to make a hard reset, but it's not really necessary */
195
1da177e4 196 /* In case some other card was probing here, reset interrupts */
68ea9de3 197 aha1542_intr_reset(sh->io_port); /* reset interrupts, so they don't block */
1da177e4 198
68ea9de3 199 outb(SRST | IRST /*|SCRST */ , CONTROL(sh->io_port));
1da177e4
LT
200
201 mdelay(20); /* Wait a little bit for things to settle down. */
202
1da177e4 203 /* Expect INIT and IDLE, any of the others are bad */
68ea9de3 204 if (!wait_mask(STATUS(sh->io_port), STATMASK, INIT | IDLE, STST | DIAGF | INVDCMD | DF | CDF, 0))
a13b3722 205 return 0;
1da177e4 206
1da177e4 207 /* Shouldn't have generated any interrupts during reset */
68ea9de3 208 if (inb(INTRFLAGS(sh->io_port)) & INTRMASK)
a13b3722 209 return 0;
1da177e4 210
1da177e4
LT
211 /* Perform a host adapter inquiry instead so we do not need to set
212 up the mailboxes ahead of time */
213
68ea9de3 214 aha1542_outb(sh->io_port, CMD_INQUIRY);
1da177e4 215
cad2fc72 216 for (i = 0; i < 4; i++) {
68ea9de3 217 if (!wait_mask(STATUS(sh->io_port), DF, DF, 0, 0))
a13b3722 218 return 0;
68ea9de3 219 inquiry_result[i] = inb(DATA(sh->io_port));
1da177e4
LT
220 }
221
1da177e4 222 /* Reading port should reset DF */
68ea9de3 223 if (inb(STATUS(sh->io_port)) & DF)
a13b3722 224 return 0;
1da177e4 225
1da177e4 226 /* When HACC, command is completed, and we're though testing */
68ea9de3 227 if (!wait_mask(INTRFLAGS(sh->io_port), HACC, HACC, 0, 0))
a13b3722 228 return 0;
1da177e4 229
1da177e4 230 /* Clear interrupts */
68ea9de3 231 outb(IRST, CONTROL(sh->io_port));
1da177e4 232
bdebe224 233 return 1;
1da177e4
LT
234}
235
1b0224b0 236static irqreturn_t aha1542_interrupt(int irq, void *dev_id)
1da177e4 237{
1b0224b0 238 struct Scsi_Host *sh = dev_id;
c2532f68 239 struct aha1542_hostdata *aha1542 = shost_priv(sh);
55b28f9f 240 void (*my_done)(struct scsi_cmnd *) = NULL;
1da177e4
LT
241 int errstatus, mbi, mbo, mbistatus;
242 int number_serviced;
243 unsigned long flags;
55b28f9f 244 struct scsi_cmnd *tmp_cmd;
1da177e4 245 int flag;
e98878f7
OZ
246 struct mailbox *mb = aha1542->mb;
247 struct ccb *ccb = aha1542->ccb;
1da177e4
LT
248
249#ifdef DEBUG
250 {
c2532f68 251 flag = inb(INTRFLAGS(sh->io_port));
2906b3ce 252 shost_printk(KERN_DEBUG, sh, "aha1542_intr_handle: ");
1da177e4
LT
253 if (!(flag & ANYINTR))
254 printk("no interrupt?");
255 if (flag & MBIF)
256 printk("MBIF ");
257 if (flag & MBOA)
258 printk("MBOF ");
259 if (flag & HACC)
260 printk("HACC ");
261 if (flag & SCRD)
262 printk("SCRD ");
c2532f68 263 printk("status %02x\n", inb(STATUS(sh->io_port)));
1da177e4
LT
264 };
265#endif
266 number_serviced = 0;
1da177e4 267
1b0224b0
OZ
268 spin_lock_irqsave(sh->host_lock, flags);
269 while (1) {
c2532f68 270 flag = inb(INTRFLAGS(sh->io_port));
1da177e4
LT
271
272 /* Check for unusual interrupts. If any of these happen, we should
273 probably do something special, but for now just printing a message
274 is sufficient. A SCSI reset detected is something that we really
275 need to deal with in some way. */
276 if (flag & ~MBIF) {
277 if (flag & MBOA)
278 printk("MBOF ");
279 if (flag & HACC)
280 printk("HACC ");
dfd7c991 281 if (flag & SCRD)
1da177e4 282 printk("SCRD ");
1da177e4 283 }
c2532f68 284 aha1542_intr_reset(sh->io_port);
1da177e4 285
e98878f7 286 mbi = aha1542->aha1542_last_mbi_used + 1;
1da177e4
LT
287 if (mbi >= 2 * AHA1542_MAILBOXES)
288 mbi = AHA1542_MAILBOXES;
289
290 do {
291 if (mb[mbi].status != 0)
292 break;
293 mbi++;
294 if (mbi >= 2 * AHA1542_MAILBOXES)
295 mbi = AHA1542_MAILBOXES;
e98878f7 296 } while (mbi != aha1542->aha1542_last_mbi_used);
1da177e4
LT
297
298 if (mb[mbi].status == 0) {
1b0224b0 299 spin_unlock_irqrestore(sh->host_lock, flags);
1da177e4 300 /* Hmm, no mail. Must have read it the last time around */
dfd7c991 301 if (!number_serviced)
2906b3ce 302 shost_printk(KERN_WARNING, sh, "interrupt received, but no mail.\n");
1b0224b0 303 return IRQ_HANDLED;
1da177e4
LT
304 };
305
10be6250 306 mbo = (scsi2int(mb[mbi].ccbptr) - (isa_virt_to_bus(&ccb[0]))) / sizeof(struct ccb);
1da177e4
LT
307 mbistatus = mb[mbi].status;
308 mb[mbi].status = 0;
e98878f7 309 aha1542->aha1542_last_mbi_used = mbi;
1da177e4
LT
310
311#ifdef DEBUG
fde1fb8a
OZ
312 if (ccb[mbo].tarstat | ccb[mbo].hastat)
313 shost_printk(KERN_DEBUG, sh, "aha1542_command: returning %x (status %d)\n",
314 ccb[mbo].tarstat + ((int) ccb[mbo].hastat << 16), mb[mbi].status);
1da177e4
LT
315#endif
316
317 if (mbistatus == 3)
318 continue; /* Aborted command not found */
319
320#ifdef DEBUG
2906b3ce 321 shost_printk(KERN_DEBUG, sh, "...done %d %d\n", mbo, mbi);
1da177e4
LT
322#endif
323
55b28f9f 324 tmp_cmd = aha1542->int_cmds[mbo];
1da177e4 325
55b28f9f 326 if (!tmp_cmd || !tmp_cmd->scsi_done) {
1b0224b0 327 spin_unlock_irqrestore(sh->host_lock, flags);
2906b3ce
OZ
328 shost_printk(KERN_WARNING, sh, "Unexpected interrupt\n");
329 shost_printk(KERN_WARNING, sh, "tarstat=%x, hastat=%x idlun=%x ccb#=%d\n", ccb[mbo].tarstat,
1da177e4 330 ccb[mbo].hastat, ccb[mbo].idlun, mbo);
1b0224b0 331 return IRQ_HANDLED;
1da177e4 332 }
55b28f9f
OZ
333 my_done = tmp_cmd->scsi_done;
334 kfree(tmp_cmd->host_scribble);
335 tmp_cmd->host_scribble = NULL;
1da177e4
LT
336 /* Fetch the sense data, and tuck it away, in the required slot. The
337 Adaptec automatically fetches it, and there is no guarantee that
338 we will still have it in the cdb when we come back */
339 if (ccb[mbo].tarstat == 2)
55b28f9f 340 memcpy(tmp_cmd->sense_buffer, &ccb[mbo].cdb[ccb[mbo].cdblen],
b80ca4f7 341 SCSI_SENSE_BUFFERSIZE);
1da177e4
LT
342
343
344 /* is there mail :-) */
345
346 /* more error checking left out here */
347 if (mbistatus != 1)
348 /* This is surely wrong, but I don't know what's right */
349 errstatus = makecode(ccb[mbo].hastat, ccb[mbo].tarstat);
350 else
351 errstatus = 0;
352
353#ifdef DEBUG
354 if (errstatus)
2906b3ce 355 shost_printk(KERN_DEBUG, sh, "(aha1542 error:%x %x %x) ", errstatus,
1da177e4 356 ccb[mbo].hastat, ccb[mbo].tarstat);
6ddc8cf4
OZ
357 if (ccb[mbo].tarstat == 2)
358 print_hex_dump_bytes("sense: ", DUMP_PREFIX_NONE, &ccb[mbo].cdb[ccb[mbo].cdblen], 12);
fde1fb8a
OZ
359 if (errstatus)
360 printk("aha1542_intr_handle: returning %6x\n", errstatus);
361#endif
55b28f9f
OZ
362 tmp_cmd->result = errstatus;
363 aha1542->int_cmds[mbo] = NULL; /* This effectively frees up the mailbox slot, as
e98878f7 364 far as queuecommand is concerned */
55b28f9f 365 my_done(tmp_cmd);
1da177e4
LT
366 number_serviced++;
367 };
368}
369
1b0224b0 370static int aha1542_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *cmd)
09a44833 371{
2906b3ce 372 struct aha1542_hostdata *aha1542 = shost_priv(sh);
cb5b570c 373 u8 direction;
55b28f9f
OZ
374 u8 target = cmd->device->id;
375 u8 lun = cmd->device->lun;
1da177e4 376 unsigned long flags;
55b28f9f 377 int bufflen = scsi_bufflen(cmd);
8c08a621 378 int mbo, sg_count;
e98878f7
OZ
379 struct mailbox *mb = aha1542->mb;
380 struct ccb *ccb = aha1542->ccb;
8c08a621 381 struct chain *cptr;
1da177e4 382
55b28f9f 383 if (*cmd->cmnd == REQUEST_SENSE) {
1da177e4 384 /* Don't do the command - we have the sense data already */
55b28f9f 385 cmd->result = 0;
1b0224b0 386 cmd->scsi_done(cmd);
1da177e4
LT
387 return 0;
388 }
389#ifdef DEBUG
764a0c7e
OZ
390 {
391 int i = -1;
392 if (*cmd->cmnd == READ_10 || *cmd->cmnd == WRITE_10)
393 i = xscsi2int(cmd->cmnd + 2);
394 else if (*cmd->cmnd == READ_6 || *cmd->cmnd == WRITE_6)
395 i = scsi2int(cmd->cmnd + 2);
396 shost_printk(KERN_DEBUG, sh, "aha1542_queuecommand: dev %d cmd %02x pos %d len %d",
397 target, *cmd->cmnd, i, bufflen);
398 print_hex_dump_bytes("command: ", DUMP_PREFIX_NONE, cmd->cmnd, cmd->cmd_len);
399 }
1da177e4 400#endif
8c08a621
OZ
401 if (bufflen) { /* allocate memory before taking host_lock */
402 sg_count = scsi_sg_count(cmd);
403 cptr = kmalloc(sizeof(*cptr) * sg_count, GFP_KERNEL | GFP_DMA);
404 if (!cptr)
405 return SCSI_MLQUEUE_HOST_BUSY;
406 }
407
1da177e4
LT
408 /* Use the outgoing mailboxes in a round-robin fashion, because this
409 is how the host adapter will scan for them */
410
1b0224b0 411 spin_lock_irqsave(sh->host_lock, flags);
e98878f7 412 mbo = aha1542->aha1542_last_mbo_used + 1;
1da177e4
LT
413 if (mbo >= AHA1542_MAILBOXES)
414 mbo = 0;
415
416 do {
55b28f9f 417 if (mb[mbo].status == 0 && aha1542->int_cmds[mbo] == NULL)
1da177e4
LT
418 break;
419 mbo++;
420 if (mbo >= AHA1542_MAILBOXES)
421 mbo = 0;
e98878f7 422 } while (mbo != aha1542->aha1542_last_mbo_used);
1da177e4 423
55b28f9f 424 if (mb[mbo].status || aha1542->int_cmds[mbo])
1da177e4
LT
425 panic("Unable to find empty mailbox for aha1542.\n");
426
55b28f9f 427 aha1542->int_cmds[mbo] = cmd; /* This will effectively prevent someone else from
e98878f7 428 screwing with this cdb. */
1da177e4 429
e98878f7 430 aha1542->aha1542_last_mbo_used = mbo;
1da177e4
LT
431
432#ifdef DEBUG
1b0224b0 433 shost_printk(KERN_DEBUG, sh, "Sending command (%d %p)...", mbo, cmd->scsi_done);
1da177e4
LT
434#endif
435
10be6250 436 any2scsi(mb[mbo].ccbptr, isa_virt_to_bus(&ccb[mbo])); /* This gets trashed for some reason */
1da177e4
LT
437
438 memset(&ccb[mbo], 0, sizeof(struct ccb));
439
55b28f9f 440 ccb[mbo].cdblen = cmd->cmd_len;
1da177e4
LT
441
442 direction = 0;
55b28f9f 443 if (*cmd->cmnd == READ_10 || *cmd->cmnd == READ_6)
1da177e4 444 direction = 8;
55b28f9f 445 else if (*cmd->cmnd == WRITE_10 || *cmd->cmnd == WRITE_6)
1da177e4
LT
446 direction = 16;
447
55b28f9f 448 memcpy(ccb[mbo].cdb, cmd->cmnd, ccb[mbo].cdblen);
1da177e4 449
fc3fdfcc 450 if (bufflen) {
51cf2249 451 struct scatterlist *sg;
8c08a621 452 int i;
6ddc8cf4 453
1da177e4 454 ccb[mbo].op = 2; /* SCSI Initiator Command w/scatter-gather */
8c08a621 455 cmd->host_scribble = (void *)cptr;
55b28f9f 456 scsi_for_each_sg(cmd, sg, sg_count, i) {
10be6250
OZ
457 any2scsi(cptr[i].dataptr, isa_page_to_bus(sg_page(sg))
458 + sg->offset);
51cf2249 459 any2scsi(cptr[i].datalen, sg->length);
1da177e4 460 };
fc3fdfcc 461 any2scsi(ccb[mbo].datalen, sg_count * sizeof(struct chain));
10be6250 462 any2scsi(ccb[mbo].dataptr, isa_virt_to_bus(cptr));
1da177e4 463#ifdef DEBUG
6ddc8cf4
OZ
464 shost_printk(KERN_DEBUG, sh, "cptr %p: ", cptr);
465 print_hex_dump_bytes("cptr: ", DUMP_PREFIX_NONE, cptr, 18);
1da177e4
LT
466#endif
467 } else {
468 ccb[mbo].op = 0; /* SCSI Initiator Command */
55b28f9f 469 cmd->host_scribble = NULL;
fc3fdfcc
BH
470 any2scsi(ccb[mbo].datalen, 0);
471 any2scsi(ccb[mbo].dataptr, 0);
1da177e4
LT
472 };
473 ccb[mbo].idlun = (target & 7) << 5 | direction | (lun & 7); /*SCSI Target Id */
474 ccb[mbo].rsalen = 16;
475 ccb[mbo].linkptr[0] = ccb[mbo].linkptr[1] = ccb[mbo].linkptr[2] = 0;
476 ccb[mbo].commlinkid = 0;
477
478#ifdef DEBUG
6ddc8cf4 479 print_hex_dump_bytes("sending: ", DUMP_PREFIX_NONE, &ccb[mbo], sizeof(ccb[mbo]) - 10);
1b0224b0 480 printk("aha1542_queuecommand: now waiting for interrupt ");
1da177e4 481#endif
1b0224b0
OZ
482 mb[mbo].status = 1;
483 aha1542_outb(cmd->device->host->io_port, CMD_START_SCSI);
484 spin_unlock_irqrestore(sh->host_lock, flags);
1da177e4
LT
485
486 return 0;
487}
488
489/* Initialize mailboxes */
68ea9de3 490static void setup_mailboxes(struct Scsi_Host *sh)
1da177e4 491{
c2532f68 492 struct aha1542_hostdata *aha1542 = shost_priv(sh);
1da177e4 493 int i;
e98878f7
OZ
494 struct mailbox *mb = aha1542->mb;
495 struct ccb *ccb = aha1542->ccb;
1da177e4 496
cad2fc72 497 u8 mb_cmd[5] = { CMD_MBINIT, AHA1542_MAILBOXES, 0, 0, 0};
1da177e4 498
1da177e4
LT
499 for (i = 0; i < AHA1542_MAILBOXES; i++) {
500 mb[i].status = mb[AHA1542_MAILBOXES + i].status = 0;
10be6250 501 any2scsi(mb[i].ccbptr, isa_virt_to_bus(&ccb[i]));
1da177e4 502 };
68ea9de3 503 aha1542_intr_reset(sh->io_port); /* reset interrupts, so they don't block */
cad2fc72 504 any2scsi((mb_cmd + 2), isa_virt_to_bus(mb));
68ea9de3 505 if (aha1542_out(sh->io_port, mb_cmd, 5))
2906b3ce 506 shost_printk(KERN_ERR, sh, "failed setting up mailboxes\n");
68ea9de3 507 aha1542_intr_reset(sh->io_port);
1da177e4
LT
508}
509
68ea9de3 510static int aha1542_getconfig(struct Scsi_Host *sh)
1da177e4 511{
cb5b570c 512 u8 inquiry_result[3];
1da177e4 513 int i;
68ea9de3 514 i = inb(STATUS(sh->io_port));
1da177e4 515 if (i & DF) {
68ea9de3 516 i = inb(DATA(sh->io_port));
1da177e4 517 };
68ea9de3
OZ
518 aha1542_outb(sh->io_port, CMD_RETCONF);
519 aha1542_in(sh->io_port, inquiry_result, 3, 0);
520 if (!wait_mask(INTRFLAGS(sh->io_port), INTRMASK, HACC, 0, 0))
2906b3ce 521 shost_printk(KERN_ERR, sh, "error querying board settings\n");
68ea9de3 522 aha1542_intr_reset(sh->io_port);
1da177e4
LT
523 switch (inquiry_result[0]) {
524 case 0x80:
68ea9de3 525 sh->dma_channel = 7;
1da177e4
LT
526 break;
527 case 0x40:
68ea9de3 528 sh->dma_channel = 6;
1da177e4
LT
529 break;
530 case 0x20:
68ea9de3 531 sh->dma_channel = 5;
1da177e4
LT
532 break;
533 case 0x01:
68ea9de3 534 sh->dma_channel = 0;
1da177e4
LT
535 break;
536 case 0:
537 /* This means that the adapter, although Adaptec 1542 compatible, doesn't use a DMA channel.
538 Currently only aware of the BusLogic BT-445S VL-Bus adapter which needs this. */
68ea9de3 539 sh->dma_channel = 0xFF;
1da177e4
LT
540 break;
541 default:
2906b3ce 542 shost_printk(KERN_ERR, sh, "Unable to determine DMA channel.\n");
1da177e4
LT
543 return -1;
544 };
545 switch (inquiry_result[1]) {
546 case 0x40:
68ea9de3 547 sh->irq = 15;
1da177e4
LT
548 break;
549 case 0x20:
68ea9de3 550 sh->irq = 14;
1da177e4
LT
551 break;
552 case 0x8:
68ea9de3 553 sh->irq = 12;
1da177e4
LT
554 break;
555 case 0x4:
68ea9de3 556 sh->irq = 11;
1da177e4
LT
557 break;
558 case 0x2:
68ea9de3 559 sh->irq = 10;
1da177e4
LT
560 break;
561 case 0x1:
68ea9de3 562 sh->irq = 9;
1da177e4
LT
563 break;
564 default:
2906b3ce 565 shost_printk(KERN_ERR, sh, "Unable to determine IRQ level.\n");
1da177e4
LT
566 return -1;
567 };
68ea9de3 568 sh->this_id = inquiry_result[2] & 7;
1da177e4
LT
569 return 0;
570}
571
572/* This function should only be called for 1542C boards - we can detect
573 the special firmware settings and unlock the board */
574
68ea9de3 575static int aha1542_mbenable(struct Scsi_Host *sh)
1da177e4 576{
cb5b570c
OZ
577 static u8 mbenable_cmd[3];
578 static u8 mbenable_result[2];
1da177e4
LT
579 int retval;
580
581 retval = BIOS_TRANSLATION_6432;
582
68ea9de3
OZ
583 aha1542_outb(sh->io_port, CMD_EXTBIOS);
584 if (aha1542_in(sh->io_port, mbenable_result, 2, 100))
1da177e4 585 return retval;
68ea9de3 586 if (!wait_mask(INTRFLAGS(sh->io_port), INTRMASK, HACC, 0, 100))
2093bfa1 587 goto fail;
68ea9de3 588 aha1542_intr_reset(sh->io_port);
1da177e4
LT
589
590 if ((mbenable_result[0] & 0x08) || mbenable_result[1]) {
591 mbenable_cmd[0] = CMD_MBENABLE;
592 mbenable_cmd[1] = 0;
593 mbenable_cmd[2] = mbenable_result[1];
594
595 if ((mbenable_result[0] & 0x08) && (mbenable_result[1] & 0x03))
596 retval = BIOS_TRANSLATION_25563;
597
68ea9de3 598 if (aha1542_out(sh->io_port, mbenable_cmd, 3))
2093bfa1 599 goto fail;
1da177e4
LT
600 };
601 while (0) {
602fail:
2906b3ce 603 shost_printk(KERN_ERR, sh, "Mailbox init failed\n");
1da177e4 604 }
68ea9de3 605 aha1542_intr_reset(sh->io_port);
1da177e4
LT
606 return retval;
607}
608
609/* Query the board to find out if it is a 1542 or a 1740, or whatever. */
68ea9de3 610static int aha1542_query(struct Scsi_Host *sh)
1da177e4 611{
68ea9de3 612 struct aha1542_hostdata *aha1542 = shost_priv(sh);
cb5b570c 613 u8 inquiry_result[4];
1da177e4 614 int i;
68ea9de3 615 i = inb(STATUS(sh->io_port));
1da177e4 616 if (i & DF) {
68ea9de3 617 i = inb(DATA(sh->io_port));
1da177e4 618 };
68ea9de3
OZ
619 aha1542_outb(sh->io_port, CMD_INQUIRY);
620 aha1542_in(sh->io_port, inquiry_result, 4, 0);
621 if (!wait_mask(INTRFLAGS(sh->io_port), INTRMASK, HACC, 0, 0))
2906b3ce 622 shost_printk(KERN_ERR, sh, "error querying card type\n");
68ea9de3 623 aha1542_intr_reset(sh->io_port);
1da177e4 624
68ea9de3 625 aha1542->bios_translation = BIOS_TRANSLATION_6432; /* Default case */
1da177e4
LT
626
627 /* For an AHA1740 series board, we ignore the board since there is a
628 hardware bug which can lead to wrong blocks being returned if the board
629 is operating in the 1542 emulation mode. Since there is an extended mode
630 driver, we simply ignore the board and let the 1740 driver pick it up.
631 */
632
633 if (inquiry_result[0] == 0x43) {
2906b3ce 634 shost_printk(KERN_INFO, sh, "Emulation mode not supported for AHA-1740 hardware, use aha1740 driver instead.\n");
1da177e4
LT
635 return 1;
636 };
637
638 /* Always call this - boards that do not support extended bios translation
639 will ignore the command, and we will set the proper default */
640
68ea9de3 641 aha1542->bios_translation = aha1542_mbenable(sh);
1da177e4
LT
642
643 return 0;
644}
645
f71429ab 646static u8 dma_speed_hw(int dma_speed)
1da177e4 647{
f71429ab
OZ
648 switch (dma_speed) {
649 case 5:
650 return 0x00;
651 case 6:
652 return 0x04;
653 case 7:
654 return 0x01;
655 case 8:
656 return 0x02;
657 case 10:
658 return 0x03;
1da177e4 659 }
1da177e4 660
f71429ab 661 return 0xff; /* invalid */
1da177e4
LT
662}
663
f71429ab 664/* Set the Bus on/off-times as not to ruin floppy performance */
37d607bd 665static void aha1542_set_bus_times(struct Scsi_Host *sh, int bus_on, int bus_off, int dma_speed)
1da177e4 666{
37d607bd
OZ
667 if (bus_on > 0) {
668 u8 oncmd[] = { CMD_BUSON_TIME, clamp(bus_on, 2, 15) };
1da177e4 669
37d607bd
OZ
670 aha1542_intr_reset(sh->io_port);
671 if (aha1542_out(sh->io_port, oncmd, 2))
f71429ab
OZ
672 goto fail;
673 }
1da177e4 674
37d607bd
OZ
675 if (bus_off > 0) {
676 u8 offcmd[] = { CMD_BUSOFF_TIME, clamp(bus_off, 1, 64) };
1da177e4 677
37d607bd
OZ
678 aha1542_intr_reset(sh->io_port);
679 if (aha1542_out(sh->io_port, offcmd, 2))
f71429ab
OZ
680 goto fail;
681 }
1da177e4 682
37d607bd
OZ
683 if (dma_speed_hw(dma_speed) != 0xff) {
684 u8 dmacmd[] = { CMD_DMASPEED, dma_speed_hw(dma_speed) };
b847fd0d 685
37d607bd
OZ
686 aha1542_intr_reset(sh->io_port);
687 if (aha1542_out(sh->io_port, dmacmd, 2))
b847fd0d
OZ
688 goto fail;
689 }
37d607bd 690 aha1542_intr_reset(sh->io_port);
b847fd0d
OZ
691 return;
692fail:
2906b3ce 693 shost_printk(KERN_ERR, sh, "setting bus on/off-time failed\n");
37d607bd 694 aha1542_intr_reset(sh->io_port);
b847fd0d
OZ
695}
696
1da177e4 697/* return non-zero on detection */
643a7c43 698static struct Scsi_Host *aha1542_hw_init(struct scsi_host_template *tpnt, struct device *pdev, int indx)
1da177e4 699{
f71429ab 700 unsigned int base_io = io[indx];
c2532f68 701 struct Scsi_Host *sh;
e98878f7 702 struct aha1542_hostdata *aha1542;
2906b3ce 703 char dma_info[] = "no DMA";
1da177e4 704
3a70c006
OZ
705 if (base_io == 0)
706 return NULL;
1da177e4 707
3a70c006
OZ
708 if (!request_region(base_io, AHA1542_REGION_SIZE, "aha1542"))
709 return NULL;
1da177e4 710
c2532f68
OZ
711 sh = scsi_host_alloc(tpnt, sizeof(struct aha1542_hostdata));
712 if (!sh)
3a70c006 713 goto release;
c2532f68 714 aha1542 = shost_priv(sh);
b847fd0d 715
68ea9de3
OZ
716 sh->unique_id = base_io;
717 sh->io_port = base_io;
718 sh->n_io_port = AHA1542_REGION_SIZE;
719 aha1542->aha1542_last_mbi_used = 2 * AHA1542_MAILBOXES - 1;
720 aha1542->aha1542_last_mbo_used = AHA1542_MAILBOXES - 1;
721
722 if (!aha1542_test_port(sh))
3a70c006 723 goto unregister;
1da177e4 724
37d607bd 725 aha1542_set_bus_times(sh, bus_on[indx], bus_off[indx], dma_speed[indx]);
68ea9de3 726 if (aha1542_query(sh))
3a70c006 727 goto unregister;
68ea9de3 728 if (aha1542_getconfig(sh) == -1)
3a70c006 729 goto unregister;
1da177e4 730
c2532f68 731 if (sh->dma_channel != 0xFF)
2906b3ce
OZ
732 snprintf(dma_info, sizeof(dma_info), "DMA %d", sh->dma_channel);
733 shost_printk(KERN_INFO, sh, "Adaptec AHA-1542 (SCSI-ID %d) at IO 0x%x, IRQ %d, %s\n",
734 sh->this_id, base_io, sh->irq, dma_info);
3a70c006 735 if (aha1542->bios_translation == BIOS_TRANSLATION_25563)
2906b3ce 736 shost_printk(KERN_INFO, sh, "Using extended bios translation\n");
1da177e4 737
68ea9de3 738 setup_mailboxes(sh);
1da177e4 739
1b0224b0 740 if (request_irq(sh->irq, aha1542_interrupt, 0, "aha1542", sh)) {
2906b3ce 741 shost_printk(KERN_ERR, sh, "Unable to allocate IRQ.\n");
3a70c006
OZ
742 goto unregister;
743 }
c2532f68
OZ
744 if (sh->dma_channel != 0xFF) {
745 if (request_dma(sh->dma_channel, "aha1542")) {
2906b3ce 746 shost_printk(KERN_ERR, sh, "Unable to allocate DMA channel.\n");
3a70c006
OZ
747 goto free_irq;
748 }
c2532f68
OZ
749 if (sh->dma_channel == 0 || sh->dma_channel >= 5) {
750 set_dma_mode(sh->dma_channel, DMA_MODE_CASCADE);
751 enable_dma(sh->dma_channel);
3a70c006
OZ
752 }
753 }
1da177e4 754
c2532f68 755 if (scsi_add_host(sh, pdev))
3a70c006 756 goto free_dma;
1da177e4 757
c2532f68 758 scsi_scan_host(sh);
1da177e4 759
c2532f68 760 return sh;
3a70c006 761free_dma:
c2532f68
OZ
762 if (sh->dma_channel != 0xff)
763 free_dma(sh->dma_channel);
3a70c006 764free_irq:
c2532f68 765 free_irq(sh->irq, sh);
3a70c006 766unregister:
c2532f68 767 scsi_host_put(sh);
3a70c006
OZ
768release:
769 release_region(base_io, AHA1542_REGION_SIZE);
1da177e4 770
643a7c43 771 return NULL;
1da177e4
LT
772}
773
c2532f68 774static int aha1542_release(struct Scsi_Host *sh)
1da177e4 775{
c2532f68
OZ
776 scsi_remove_host(sh);
777 if (sh->dma_channel != 0xff)
778 free_dma(sh->dma_channel);
779 if (sh->irq)
780 free_irq(sh->irq, sh);
781 if (sh->io_port && sh->n_io_port)
782 release_region(sh->io_port, sh->n_io_port);
783 scsi_host_put(sh);
1da177e4
LT
784 return 0;
785}
786
1da177e4 787
1da177e4
LT
788/*
789 * This is a device reset. This is handled by sending a special command
790 * to the device.
791 */
55b28f9f 792static int aha1542_dev_reset(struct scsi_cmnd *cmd)
1da177e4 793{
1b0224b0
OZ
794 struct Scsi_Host *sh = cmd->device->host;
795 struct aha1542_hostdata *aha1542 = shost_priv(sh);
1da177e4 796 unsigned long flags;
e98878f7 797 struct mailbox *mb = aha1542->mb;
55b28f9f
OZ
798 u8 target = cmd->device->id;
799 u8 lun = cmd->device->lun;
1da177e4 800 int mbo;
e98878f7 801 struct ccb *ccb = aha1542->ccb;
1da177e4 802
1b0224b0 803 spin_lock_irqsave(sh->host_lock, flags);
e98878f7 804 mbo = aha1542->aha1542_last_mbo_used + 1;
1da177e4
LT
805 if (mbo >= AHA1542_MAILBOXES)
806 mbo = 0;
807
808 do {
55b28f9f 809 if (mb[mbo].status == 0 && aha1542->int_cmds[mbo] == NULL)
1da177e4
LT
810 break;
811 mbo++;
812 if (mbo >= AHA1542_MAILBOXES)
813 mbo = 0;
e98878f7 814 } while (mbo != aha1542->aha1542_last_mbo_used);
1da177e4 815
55b28f9f 816 if (mb[mbo].status || aha1542->int_cmds[mbo])
1da177e4
LT
817 panic("Unable to find empty mailbox for aha1542.\n");
818
55b28f9f 819 aha1542->int_cmds[mbo] = cmd; /* This will effectively
e98878f7
OZ
820 prevent someone else from
821 screwing with this cdb. */
1da177e4 822
e98878f7 823 aha1542->aha1542_last_mbo_used = mbo;
1da177e4 824
10be6250 825 any2scsi(mb[mbo].ccbptr, isa_virt_to_bus(&ccb[mbo])); /* This gets trashed for some reason */
1da177e4
LT
826
827 memset(&ccb[mbo], 0, sizeof(struct ccb));
828
829 ccb[mbo].op = 0x81; /* BUS DEVICE RESET */
830
831 ccb[mbo].idlun = (target & 7) << 5 | (lun & 7); /*SCSI Target Id */
832
833 ccb[mbo].linkptr[0] = ccb[mbo].linkptr[1] = ccb[mbo].linkptr[2] = 0;
834 ccb[mbo].commlinkid = 0;
835
836 /*
837 * Now tell the 1542 to flush all pending commands for this
838 * target
839 */
1b0224b0
OZ
840 aha1542_outb(sh->io_port, CMD_START_SCSI);
841 spin_unlock_irqrestore(sh->host_lock, flags);
1da177e4 842
55b28f9f 843 scmd_printk(KERN_WARNING, cmd,
017560fc 844 "Trying device reset for target\n");
1da177e4
LT
845
846 return SUCCESS;
1da177e4
LT
847}
848
55b28f9f 849static int aha1542_reset(struct scsi_cmnd *cmd, u8 reset_cmd)
1da177e4 850{
1b0224b0
OZ
851 struct Scsi_Host *sh = cmd->device->host;
852 struct aha1542_hostdata *aha1542 = shost_priv(sh);
853 unsigned long flags;
1da177e4
LT
854 int i;
855
1b0224b0 856 spin_lock_irqsave(sh->host_lock, flags);
1da177e4
LT
857 /*
858 * This does a scsi reset for all devices on the bus.
859 * In principle, we could also reset the 1542 - should
860 * we do this? Try this first, and we can add that later
861 * if it turns out to be useful.
862 */
55b28f9f 863 outb(reset_cmd, CONTROL(cmd->device->host->io_port));
1da177e4 864
55b28f9f 865 if (!wait_mask(STATUS(cmd->device->host->io_port),
7061dec4 866 STATMASK, IDLE, STST | DIAGF | INVDCMD | DF | CDF, 0)) {
1b0224b0 867 spin_unlock_irqrestore(sh->host_lock, flags);
a13b3722
OZ
868 return FAILED;
869 }
1b0224b0 870
8537cba8
OZ
871 /*
872 * We need to do this too before the 1542 can interact with
873 * us again after host reset.
874 */
875 if (reset_cmd & HRST)
68ea9de3 876 setup_mailboxes(cmd->device->host);
1b0224b0 877
1da177e4
LT
878 /*
879 * Now try to pick up the pieces. For all pending commands,
880 * free any internal data structures, and basically clear things
881 * out. We do not try and restart any commands or anything -
882 * the strategy handler takes care of that crap.
883 */
2906b3ce 884 shost_printk(KERN_WARNING, cmd->device->host, "Sent BUS RESET to scsi host %d\n", cmd->device->host->host_no);
1da177e4
LT
885
886 for (i = 0; i < AHA1542_MAILBOXES; i++) {
55b28f9f
OZ
887 if (aha1542->int_cmds[i] != NULL) {
888 struct scsi_cmnd *tmp_cmd;
889 tmp_cmd = aha1542->int_cmds[i];
1da177e4 890
55b28f9f 891 if (tmp_cmd->device->soft_reset) {
1da177e4
LT
892 /*
893 * If this device implements the soft reset option,
894 * then it is still holding onto the command, and
895 * may yet complete it. In this case, we don't
896 * flush the data.
897 */
898 continue;
899 }
55b28f9f
OZ
900 kfree(tmp_cmd->host_scribble);
901 tmp_cmd->host_scribble = NULL;
902 aha1542->int_cmds[i] = NULL;
e98878f7 903 aha1542->mb[i].status = 0;
1da177e4
LT
904 }
905 }
906
1b0224b0 907 spin_unlock_irqrestore(sh->host_lock, flags);
1da177e4 908 return SUCCESS;
1da177e4
LT
909}
910
55b28f9f 911static int aha1542_bus_reset(struct scsi_cmnd *cmd)
1da177e4 912{
55b28f9f 913 return aha1542_reset(cmd, SCRST);
8537cba8 914}
1da177e4 915
55b28f9f 916static int aha1542_host_reset(struct scsi_cmnd *cmd)
8537cba8 917{
55b28f9f 918 return aha1542_reset(cmd, HRST | SCRST);
1da177e4
LT
919}
920
1da177e4 921static int aha1542_biosparam(struct scsi_device *sdev,
17787a09 922 struct block_device *bdev, sector_t capacity, int geom[])
1da177e4 923{
e98878f7 924 struct aha1542_hostdata *aha1542 = shost_priv(sdev->host);
1da177e4 925
17787a09
OZ
926 if (capacity >= 0x200000 &&
927 aha1542->bios_translation == BIOS_TRANSLATION_25563) {
1da177e4 928 /* Please verify that this is the same as what DOS returns */
17787a09
OZ
929 geom[0] = 255; /* heads */
930 geom[1] = 63; /* sectors */
1da177e4 931 } else {
17787a09
OZ
932 geom[0] = 64; /* heads */
933 geom[1] = 32; /* sectors */
1da177e4 934 }
17787a09 935 geom[2] = sector_div(capacity, geom[0] * geom[1]); /* cylinders */
1da177e4
LT
936
937 return 0;
938}
939MODULE_LICENSE("GPL");
940
d0be4a7d 941static struct scsi_host_template driver_template = {
643a7c43 942 .module = THIS_MODULE,
1da177e4
LT
943 .proc_name = "aha1542",
944 .name = "Adaptec 1542",
1da177e4 945 .queuecommand = aha1542_queuecommand,
1da177e4
LT
946 .eh_device_reset_handler= aha1542_dev_reset,
947 .eh_bus_reset_handler = aha1542_bus_reset,
948 .eh_host_reset_handler = aha1542_host_reset,
949 .bios_param = aha1542_biosparam,
950 .can_queue = AHA1542_MAILBOXES,
951 .this_id = 7,
10be6250
OZ
952 .sg_tablesize = 16,
953 .cmd_per_lun = 1,
1da177e4
LT
954 .unchecked_isa_dma = 1,
955 .use_clustering = ENABLE_CLUSTERING,
956};
643a7c43
OZ
957
958static int aha1542_isa_match(struct device *pdev, unsigned int ndev)
959{
960 struct Scsi_Host *sh = aha1542_hw_init(&driver_template, pdev, ndev);
961
962 if (!sh)
963 return 0;
964
965 dev_set_drvdata(pdev, sh);
966 return 1;
967}
968
969static int aha1542_isa_remove(struct device *pdev,
970 unsigned int ndev)
971{
972 aha1542_release(dev_get_drvdata(pdev));
973 dev_set_drvdata(pdev, NULL);
974 return 0;
975}
976
977static struct isa_driver aha1542_isa_driver = {
978 .match = aha1542_isa_match,
979 .remove = aha1542_isa_remove,
980 .driver = {
981 .name = "aha1542"
982 },
983};
984static int isa_registered;
985
986#ifdef CONFIG_PNP
987static struct pnp_device_id aha1542_pnp_ids[] = {
988 { .id = "ADP1542" },
989 { .id = "" }
990};
991MODULE_DEVICE_TABLE(pnp, aha1542_pnp_ids);
992
993static int aha1542_pnp_probe(struct pnp_dev *pdev, const struct pnp_device_id *id)
994{
995 int indx;
996 struct Scsi_Host *sh;
997
f71429ab
OZ
998 for (indx = 0; indx < ARRAY_SIZE(io); indx++) {
999 if (io[indx])
643a7c43
OZ
1000 continue;
1001
1002 if (pnp_activate_dev(pdev) < 0)
1003 continue;
1004
f71429ab 1005 io[indx] = pnp_port_start(pdev, 0);
643a7c43
OZ
1006
1007 /* The card can be queried for its DMA, we have
1008 the DMA set up that is enough */
1009
2906b3ce 1010 dev_info(&pdev->dev, "ISAPnP found an AHA1535 at I/O 0x%03X", io[indx]);
643a7c43
OZ
1011 }
1012
1013 sh = aha1542_hw_init(&driver_template, &pdev->dev, indx);
1014 if (!sh)
1015 return -ENODEV;
1016
1017 pnp_set_drvdata(pdev, sh);
1018 return 0;
1019}
1020
1021static void aha1542_pnp_remove(struct pnp_dev *pdev)
1022{
1023 aha1542_release(pnp_get_drvdata(pdev));
1024 pnp_set_drvdata(pdev, NULL);
1025}
1026
1027static struct pnp_driver aha1542_pnp_driver = {
1028 .name = "aha1542",
1029 .id_table = aha1542_pnp_ids,
1030 .probe = aha1542_pnp_probe,
1031 .remove = aha1542_pnp_remove,
1032};
1033static int pnp_registered;
1034#endif /* CONFIG_PNP */
1035
1036static int __init aha1542_init(void)
1037{
1038 int ret = 0;
643a7c43
OZ
1039
1040#ifdef CONFIG_PNP
1041 if (isapnp) {
1042 ret = pnp_register_driver(&aha1542_pnp_driver);
1043 if (!ret)
1044 pnp_registered = 1;
1045 }
1046#endif
1047 ret = isa_register_driver(&aha1542_isa_driver, MAXBOARDS);
1048 if (!ret)
1049 isa_registered = 1;
1050
1051#ifdef CONFIG_PNP
1052 if (pnp_registered)
1053 ret = 0;
1054#endif
1055 if (isa_registered)
1056 ret = 0;
1057
1058 return ret;
1059}
1060
1061static void __exit aha1542_exit(void)
1062{
1063#ifdef CONFIG_PNP
1064 if (pnp_registered)
1065 pnp_unregister_driver(&aha1542_pnp_driver);
1066#endif
1067 if (isa_registered)
1068 isa_unregister_driver(&aha1542_isa_driver);
1069}
1070
1071module_init(aha1542_init);
1072module_exit(aha1542_exit);