ACPI / SBS: Add 5 us delay to fix SBS hangs on MacBook
[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);
1da177e4 378 int mbo;
e98878f7
OZ
379 struct mailbox *mb = aha1542->mb;
380 struct ccb *ccb = aha1542->ccb;
1da177e4 381
55b28f9f 382 if (*cmd->cmnd == REQUEST_SENSE) {
1da177e4 383 /* Don't do the command - we have the sense data already */
55b28f9f 384 cmd->result = 0;
1b0224b0 385 cmd->scsi_done(cmd);
1da177e4
LT
386 return 0;
387 }
388#ifdef DEBUG
764a0c7e
OZ
389 {
390 int i = -1;
391 if (*cmd->cmnd == READ_10 || *cmd->cmnd == WRITE_10)
392 i = xscsi2int(cmd->cmnd + 2);
393 else if (*cmd->cmnd == READ_6 || *cmd->cmnd == WRITE_6)
394 i = scsi2int(cmd->cmnd + 2);
395 shost_printk(KERN_DEBUG, sh, "aha1542_queuecommand: dev %d cmd %02x pos %d len %d",
396 target, *cmd->cmnd, i, bufflen);
397 print_hex_dump_bytes("command: ", DUMP_PREFIX_NONE, cmd->cmnd, cmd->cmd_len);
398 }
1da177e4
LT
399#endif
400 /* Use the outgoing mailboxes in a round-robin fashion, because this
401 is how the host adapter will scan for them */
402
1b0224b0 403 spin_lock_irqsave(sh->host_lock, flags);
e98878f7 404 mbo = aha1542->aha1542_last_mbo_used + 1;
1da177e4
LT
405 if (mbo >= AHA1542_MAILBOXES)
406 mbo = 0;
407
408 do {
55b28f9f 409 if (mb[mbo].status == 0 && aha1542->int_cmds[mbo] == NULL)
1da177e4
LT
410 break;
411 mbo++;
412 if (mbo >= AHA1542_MAILBOXES)
413 mbo = 0;
e98878f7 414 } while (mbo != aha1542->aha1542_last_mbo_used);
1da177e4 415
55b28f9f 416 if (mb[mbo].status || aha1542->int_cmds[mbo])
1da177e4
LT
417 panic("Unable to find empty mailbox for aha1542.\n");
418
55b28f9f 419 aha1542->int_cmds[mbo] = cmd; /* This will effectively prevent someone else from
e98878f7 420 screwing with this cdb. */
1da177e4 421
e98878f7 422 aha1542->aha1542_last_mbo_used = mbo;
1da177e4
LT
423
424#ifdef DEBUG
1b0224b0 425 shost_printk(KERN_DEBUG, sh, "Sending command (%d %p)...", mbo, cmd->scsi_done);
1da177e4
LT
426#endif
427
10be6250 428 any2scsi(mb[mbo].ccbptr, isa_virt_to_bus(&ccb[mbo])); /* This gets trashed for some reason */
1da177e4
LT
429
430 memset(&ccb[mbo], 0, sizeof(struct ccb));
431
55b28f9f 432 ccb[mbo].cdblen = cmd->cmd_len;
1da177e4
LT
433
434 direction = 0;
55b28f9f 435 if (*cmd->cmnd == READ_10 || *cmd->cmnd == READ_6)
1da177e4 436 direction = 8;
55b28f9f 437 else if (*cmd->cmnd == WRITE_10 || *cmd->cmnd == WRITE_6)
1da177e4
LT
438 direction = 16;
439
55b28f9f 440 memcpy(ccb[mbo].cdb, cmd->cmnd, ccb[mbo].cdblen);
1da177e4 441
fc3fdfcc 442 if (bufflen) {
51cf2249 443 struct scatterlist *sg;
1da177e4 444 struct chain *cptr;
55b28f9f 445 int i, sg_count = scsi_sg_count(cmd);
6ddc8cf4 446
1da177e4 447 ccb[mbo].op = 2; /* SCSI Initiator Command w/scatter-gather */
55b28f9f 448 cmd->host_scribble = kmalloc(sizeof(*cptr)*sg_count,
fc3fdfcc 449 GFP_KERNEL | GFP_DMA);
55b28f9f 450 cptr = (struct chain *) cmd->host_scribble;
1da177e4
LT
451 if (cptr == NULL) {
452 /* free the claimed mailbox slot */
55b28f9f 453 aha1542->int_cmds[mbo] = NULL;
1b0224b0 454 spin_unlock_irqrestore(sh->host_lock, flags);
1da177e4
LT
455 return SCSI_MLQUEUE_HOST_BUSY;
456 }
55b28f9f 457 scsi_for_each_sg(cmd, sg, sg_count, i) {
10be6250
OZ
458 any2scsi(cptr[i].dataptr, isa_page_to_bus(sg_page(sg))
459 + sg->offset);
51cf2249 460 any2scsi(cptr[i].datalen, sg->length);
1da177e4 461 };
fc3fdfcc 462 any2scsi(ccb[mbo].datalen, sg_count * sizeof(struct chain));
10be6250 463 any2scsi(ccb[mbo].dataptr, isa_virt_to_bus(cptr));
1da177e4 464#ifdef DEBUG
6ddc8cf4
OZ
465 shost_printk(KERN_DEBUG, sh, "cptr %p: ", cptr);
466 print_hex_dump_bytes("cptr: ", DUMP_PREFIX_NONE, cptr, 18);
1da177e4
LT
467#endif
468 } else {
469 ccb[mbo].op = 0; /* SCSI Initiator Command */
55b28f9f 470 cmd->host_scribble = NULL;
fc3fdfcc
BH
471 any2scsi(ccb[mbo].datalen, 0);
472 any2scsi(ccb[mbo].dataptr, 0);
1da177e4
LT
473 };
474 ccb[mbo].idlun = (target & 7) << 5 | direction | (lun & 7); /*SCSI Target Id */
475 ccb[mbo].rsalen = 16;
476 ccb[mbo].linkptr[0] = ccb[mbo].linkptr[1] = ccb[mbo].linkptr[2] = 0;
477 ccb[mbo].commlinkid = 0;
478
479#ifdef DEBUG
6ddc8cf4 480 print_hex_dump_bytes("sending: ", DUMP_PREFIX_NONE, &ccb[mbo], sizeof(ccb[mbo]) - 10);
1b0224b0 481 printk("aha1542_queuecommand: now waiting for interrupt ");
1da177e4 482#endif
1b0224b0
OZ
483 mb[mbo].status = 1;
484 aha1542_outb(cmd->device->host->io_port, CMD_START_SCSI);
485 spin_unlock_irqrestore(sh->host_lock, flags);
1da177e4
LT
486
487 return 0;
488}
489
490/* Initialize mailboxes */
68ea9de3 491static void setup_mailboxes(struct Scsi_Host *sh)
1da177e4 492{
c2532f68 493 struct aha1542_hostdata *aha1542 = shost_priv(sh);
1da177e4 494 int i;
e98878f7
OZ
495 struct mailbox *mb = aha1542->mb;
496 struct ccb *ccb = aha1542->ccb;
1da177e4 497
cad2fc72 498 u8 mb_cmd[5] = { CMD_MBINIT, AHA1542_MAILBOXES, 0, 0, 0};
1da177e4 499
1da177e4
LT
500 for (i = 0; i < AHA1542_MAILBOXES; i++) {
501 mb[i].status = mb[AHA1542_MAILBOXES + i].status = 0;
10be6250 502 any2scsi(mb[i].ccbptr, isa_virt_to_bus(&ccb[i]));
1da177e4 503 };
68ea9de3 504 aha1542_intr_reset(sh->io_port); /* reset interrupts, so they don't block */
cad2fc72 505 any2scsi((mb_cmd + 2), isa_virt_to_bus(mb));
68ea9de3 506 if (aha1542_out(sh->io_port, mb_cmd, 5))
2906b3ce 507 shost_printk(KERN_ERR, sh, "failed setting up mailboxes\n");
68ea9de3 508 aha1542_intr_reset(sh->io_port);
1da177e4
LT
509}
510
68ea9de3 511static int aha1542_getconfig(struct Scsi_Host *sh)
1da177e4 512{
cb5b570c 513 u8 inquiry_result[3];
1da177e4 514 int i;
68ea9de3 515 i = inb(STATUS(sh->io_port));
1da177e4 516 if (i & DF) {
68ea9de3 517 i = inb(DATA(sh->io_port));
1da177e4 518 };
68ea9de3
OZ
519 aha1542_outb(sh->io_port, CMD_RETCONF);
520 aha1542_in(sh->io_port, inquiry_result, 3, 0);
521 if (!wait_mask(INTRFLAGS(sh->io_port), INTRMASK, HACC, 0, 0))
2906b3ce 522 shost_printk(KERN_ERR, sh, "error querying board settings\n");
68ea9de3 523 aha1542_intr_reset(sh->io_port);
1da177e4
LT
524 switch (inquiry_result[0]) {
525 case 0x80:
68ea9de3 526 sh->dma_channel = 7;
1da177e4
LT
527 break;
528 case 0x40:
68ea9de3 529 sh->dma_channel = 6;
1da177e4
LT
530 break;
531 case 0x20:
68ea9de3 532 sh->dma_channel = 5;
1da177e4
LT
533 break;
534 case 0x01:
68ea9de3 535 sh->dma_channel = 0;
1da177e4
LT
536 break;
537 case 0:
538 /* This means that the adapter, although Adaptec 1542 compatible, doesn't use a DMA channel.
539 Currently only aware of the BusLogic BT-445S VL-Bus adapter which needs this. */
68ea9de3 540 sh->dma_channel = 0xFF;
1da177e4
LT
541 break;
542 default:
2906b3ce 543 shost_printk(KERN_ERR, sh, "Unable to determine DMA channel.\n");
1da177e4
LT
544 return -1;
545 };
546 switch (inquiry_result[1]) {
547 case 0x40:
68ea9de3 548 sh->irq = 15;
1da177e4
LT
549 break;
550 case 0x20:
68ea9de3 551 sh->irq = 14;
1da177e4
LT
552 break;
553 case 0x8:
68ea9de3 554 sh->irq = 12;
1da177e4
LT
555 break;
556 case 0x4:
68ea9de3 557 sh->irq = 11;
1da177e4
LT
558 break;
559 case 0x2:
68ea9de3 560 sh->irq = 10;
1da177e4
LT
561 break;
562 case 0x1:
68ea9de3 563 sh->irq = 9;
1da177e4
LT
564 break;
565 default:
2906b3ce 566 shost_printk(KERN_ERR, sh, "Unable to determine IRQ level.\n");
1da177e4
LT
567 return -1;
568 };
68ea9de3 569 sh->this_id = inquiry_result[2] & 7;
1da177e4
LT
570 return 0;
571}
572
573/* This function should only be called for 1542C boards - we can detect
574 the special firmware settings and unlock the board */
575
68ea9de3 576static int aha1542_mbenable(struct Scsi_Host *sh)
1da177e4 577{
cb5b570c
OZ
578 static u8 mbenable_cmd[3];
579 static u8 mbenable_result[2];
1da177e4
LT
580 int retval;
581
582 retval = BIOS_TRANSLATION_6432;
583
68ea9de3
OZ
584 aha1542_outb(sh->io_port, CMD_EXTBIOS);
585 if (aha1542_in(sh->io_port, mbenable_result, 2, 100))
1da177e4 586 return retval;
68ea9de3 587 if (!wait_mask(INTRFLAGS(sh->io_port), INTRMASK, HACC, 0, 100))
2093bfa1 588 goto fail;
68ea9de3 589 aha1542_intr_reset(sh->io_port);
1da177e4
LT
590
591 if ((mbenable_result[0] & 0x08) || mbenable_result[1]) {
592 mbenable_cmd[0] = CMD_MBENABLE;
593 mbenable_cmd[1] = 0;
594 mbenable_cmd[2] = mbenable_result[1];
595
596 if ((mbenable_result[0] & 0x08) && (mbenable_result[1] & 0x03))
597 retval = BIOS_TRANSLATION_25563;
598
68ea9de3 599 if (aha1542_out(sh->io_port, mbenable_cmd, 3))
2093bfa1 600 goto fail;
1da177e4
LT
601 };
602 while (0) {
603fail:
2906b3ce 604 shost_printk(KERN_ERR, sh, "Mailbox init failed\n");
1da177e4 605 }
68ea9de3 606 aha1542_intr_reset(sh->io_port);
1da177e4
LT
607 return retval;
608}
609
610/* Query the board to find out if it is a 1542 or a 1740, or whatever. */
68ea9de3 611static int aha1542_query(struct Scsi_Host *sh)
1da177e4 612{
68ea9de3 613 struct aha1542_hostdata *aha1542 = shost_priv(sh);
cb5b570c 614 u8 inquiry_result[4];
1da177e4 615 int i;
68ea9de3 616 i = inb(STATUS(sh->io_port));
1da177e4 617 if (i & DF) {
68ea9de3 618 i = inb(DATA(sh->io_port));
1da177e4 619 };
68ea9de3
OZ
620 aha1542_outb(sh->io_port, CMD_INQUIRY);
621 aha1542_in(sh->io_port, inquiry_result, 4, 0);
622 if (!wait_mask(INTRFLAGS(sh->io_port), INTRMASK, HACC, 0, 0))
2906b3ce 623 shost_printk(KERN_ERR, sh, "error querying card type\n");
68ea9de3 624 aha1542_intr_reset(sh->io_port);
1da177e4 625
68ea9de3 626 aha1542->bios_translation = BIOS_TRANSLATION_6432; /* Default case */
1da177e4
LT
627
628 /* For an AHA1740 series board, we ignore the board since there is a
629 hardware bug which can lead to wrong blocks being returned if the board
630 is operating in the 1542 emulation mode. Since there is an extended mode
631 driver, we simply ignore the board and let the 1740 driver pick it up.
632 */
633
634 if (inquiry_result[0] == 0x43) {
2906b3ce 635 shost_printk(KERN_INFO, sh, "Emulation mode not supported for AHA-1740 hardware, use aha1740 driver instead.\n");
1da177e4
LT
636 return 1;
637 };
638
639 /* Always call this - boards that do not support extended bios translation
640 will ignore the command, and we will set the proper default */
641
68ea9de3 642 aha1542->bios_translation = aha1542_mbenable(sh);
1da177e4
LT
643
644 return 0;
645}
646
f71429ab 647static u8 dma_speed_hw(int dma_speed)
1da177e4 648{
f71429ab
OZ
649 switch (dma_speed) {
650 case 5:
651 return 0x00;
652 case 6:
653 return 0x04;
654 case 7:
655 return 0x01;
656 case 8:
657 return 0x02;
658 case 10:
659 return 0x03;
1da177e4 660 }
1da177e4 661
f71429ab 662 return 0xff; /* invalid */
1da177e4
LT
663}
664
f71429ab 665/* Set the Bus on/off-times as not to ruin floppy performance */
37d607bd 666static void aha1542_set_bus_times(struct Scsi_Host *sh, int bus_on, int bus_off, int dma_speed)
1da177e4 667{
37d607bd
OZ
668 if (bus_on > 0) {
669 u8 oncmd[] = { CMD_BUSON_TIME, clamp(bus_on, 2, 15) };
1da177e4 670
37d607bd
OZ
671 aha1542_intr_reset(sh->io_port);
672 if (aha1542_out(sh->io_port, oncmd, 2))
f71429ab
OZ
673 goto fail;
674 }
1da177e4 675
37d607bd
OZ
676 if (bus_off > 0) {
677 u8 offcmd[] = { CMD_BUSOFF_TIME, clamp(bus_off, 1, 64) };
1da177e4 678
37d607bd
OZ
679 aha1542_intr_reset(sh->io_port);
680 if (aha1542_out(sh->io_port, offcmd, 2))
f71429ab
OZ
681 goto fail;
682 }
1da177e4 683
37d607bd
OZ
684 if (dma_speed_hw(dma_speed) != 0xff) {
685 u8 dmacmd[] = { CMD_DMASPEED, dma_speed_hw(dma_speed) };
b847fd0d 686
37d607bd
OZ
687 aha1542_intr_reset(sh->io_port);
688 if (aha1542_out(sh->io_port, dmacmd, 2))
b847fd0d
OZ
689 goto fail;
690 }
37d607bd 691 aha1542_intr_reset(sh->io_port);
b847fd0d
OZ
692 return;
693fail:
2906b3ce 694 shost_printk(KERN_ERR, sh, "setting bus on/off-time failed\n");
37d607bd 695 aha1542_intr_reset(sh->io_port);
b847fd0d
OZ
696}
697
1da177e4 698/* return non-zero on detection */
643a7c43 699static struct Scsi_Host *aha1542_hw_init(struct scsi_host_template *tpnt, struct device *pdev, int indx)
1da177e4 700{
f71429ab 701 unsigned int base_io = io[indx];
c2532f68 702 struct Scsi_Host *sh;
e98878f7 703 struct aha1542_hostdata *aha1542;
2906b3ce 704 char dma_info[] = "no DMA";
1da177e4 705
3a70c006
OZ
706 if (base_io == 0)
707 return NULL;
1da177e4 708
3a70c006
OZ
709 if (!request_region(base_io, AHA1542_REGION_SIZE, "aha1542"))
710 return NULL;
1da177e4 711
c2532f68
OZ
712 sh = scsi_host_alloc(tpnt, sizeof(struct aha1542_hostdata));
713 if (!sh)
3a70c006 714 goto release;
c2532f68 715 aha1542 = shost_priv(sh);
b847fd0d 716
68ea9de3
OZ
717 sh->unique_id = base_io;
718 sh->io_port = base_io;
719 sh->n_io_port = AHA1542_REGION_SIZE;
720 aha1542->aha1542_last_mbi_used = 2 * AHA1542_MAILBOXES - 1;
721 aha1542->aha1542_last_mbo_used = AHA1542_MAILBOXES - 1;
722
723 if (!aha1542_test_port(sh))
3a70c006 724 goto unregister;
1da177e4 725
37d607bd 726 aha1542_set_bus_times(sh, bus_on[indx], bus_off[indx], dma_speed[indx]);
68ea9de3 727 if (aha1542_query(sh))
3a70c006 728 goto unregister;
68ea9de3 729 if (aha1542_getconfig(sh) == -1)
3a70c006 730 goto unregister;
1da177e4 731
c2532f68 732 if (sh->dma_channel != 0xFF)
2906b3ce
OZ
733 snprintf(dma_info, sizeof(dma_info), "DMA %d", sh->dma_channel);
734 shost_printk(KERN_INFO, sh, "Adaptec AHA-1542 (SCSI-ID %d) at IO 0x%x, IRQ %d, %s\n",
735 sh->this_id, base_io, sh->irq, dma_info);
3a70c006 736 if (aha1542->bios_translation == BIOS_TRANSLATION_25563)
2906b3ce 737 shost_printk(KERN_INFO, sh, "Using extended bios translation\n");
1da177e4 738
68ea9de3 739 setup_mailboxes(sh);
1da177e4 740
1b0224b0 741 if (request_irq(sh->irq, aha1542_interrupt, 0, "aha1542", sh)) {
2906b3ce 742 shost_printk(KERN_ERR, sh, "Unable to allocate IRQ.\n");
3a70c006
OZ
743 goto unregister;
744 }
c2532f68
OZ
745 if (sh->dma_channel != 0xFF) {
746 if (request_dma(sh->dma_channel, "aha1542")) {
2906b3ce 747 shost_printk(KERN_ERR, sh, "Unable to allocate DMA channel.\n");
3a70c006
OZ
748 goto free_irq;
749 }
c2532f68
OZ
750 if (sh->dma_channel == 0 || sh->dma_channel >= 5) {
751 set_dma_mode(sh->dma_channel, DMA_MODE_CASCADE);
752 enable_dma(sh->dma_channel);
3a70c006
OZ
753 }
754 }
1da177e4 755
c2532f68 756 if (scsi_add_host(sh, pdev))
3a70c006 757 goto free_dma;
1da177e4 758
c2532f68 759 scsi_scan_host(sh);
1da177e4 760
c2532f68 761 return sh;
3a70c006 762free_dma:
c2532f68
OZ
763 if (sh->dma_channel != 0xff)
764 free_dma(sh->dma_channel);
3a70c006 765free_irq:
c2532f68 766 free_irq(sh->irq, sh);
3a70c006 767unregister:
c2532f68 768 scsi_host_put(sh);
3a70c006
OZ
769release:
770 release_region(base_io, AHA1542_REGION_SIZE);
1da177e4 771
643a7c43 772 return NULL;
1da177e4
LT
773}
774
c2532f68 775static int aha1542_release(struct Scsi_Host *sh)
1da177e4 776{
c2532f68
OZ
777 scsi_remove_host(sh);
778 if (sh->dma_channel != 0xff)
779 free_dma(sh->dma_channel);
780 if (sh->irq)
781 free_irq(sh->irq, sh);
782 if (sh->io_port && sh->n_io_port)
783 release_region(sh->io_port, sh->n_io_port);
784 scsi_host_put(sh);
1da177e4
LT
785 return 0;
786}
787
1da177e4 788
1da177e4
LT
789/*
790 * This is a device reset. This is handled by sending a special command
791 * to the device.
792 */
55b28f9f 793static int aha1542_dev_reset(struct scsi_cmnd *cmd)
1da177e4 794{
1b0224b0
OZ
795 struct Scsi_Host *sh = cmd->device->host;
796 struct aha1542_hostdata *aha1542 = shost_priv(sh);
1da177e4 797 unsigned long flags;
e98878f7 798 struct mailbox *mb = aha1542->mb;
55b28f9f
OZ
799 u8 target = cmd->device->id;
800 u8 lun = cmd->device->lun;
1da177e4 801 int mbo;
e98878f7 802 struct ccb *ccb = aha1542->ccb;
1da177e4 803
1b0224b0 804 spin_lock_irqsave(sh->host_lock, flags);
e98878f7 805 mbo = aha1542->aha1542_last_mbo_used + 1;
1da177e4
LT
806 if (mbo >= AHA1542_MAILBOXES)
807 mbo = 0;
808
809 do {
55b28f9f 810 if (mb[mbo].status == 0 && aha1542->int_cmds[mbo] == NULL)
1da177e4
LT
811 break;
812 mbo++;
813 if (mbo >= AHA1542_MAILBOXES)
814 mbo = 0;
e98878f7 815 } while (mbo != aha1542->aha1542_last_mbo_used);
1da177e4 816
55b28f9f 817 if (mb[mbo].status || aha1542->int_cmds[mbo])
1da177e4
LT
818 panic("Unable to find empty mailbox for aha1542.\n");
819
55b28f9f 820 aha1542->int_cmds[mbo] = cmd; /* This will effectively
e98878f7
OZ
821 prevent someone else from
822 screwing with this cdb. */
1da177e4 823
e98878f7 824 aha1542->aha1542_last_mbo_used = mbo;
1da177e4 825
10be6250 826 any2scsi(mb[mbo].ccbptr, isa_virt_to_bus(&ccb[mbo])); /* This gets trashed for some reason */
1da177e4
LT
827
828 memset(&ccb[mbo], 0, sizeof(struct ccb));
829
830 ccb[mbo].op = 0x81; /* BUS DEVICE RESET */
831
832 ccb[mbo].idlun = (target & 7) << 5 | (lun & 7); /*SCSI Target Id */
833
834 ccb[mbo].linkptr[0] = ccb[mbo].linkptr[1] = ccb[mbo].linkptr[2] = 0;
835 ccb[mbo].commlinkid = 0;
836
837 /*
838 * Now tell the 1542 to flush all pending commands for this
839 * target
840 */
1b0224b0
OZ
841 aha1542_outb(sh->io_port, CMD_START_SCSI);
842 spin_unlock_irqrestore(sh->host_lock, flags);
1da177e4 843
55b28f9f 844 scmd_printk(KERN_WARNING, cmd,
017560fc 845 "Trying device reset for target\n");
1da177e4
LT
846
847 return SUCCESS;
1da177e4
LT
848}
849
55b28f9f 850static int aha1542_reset(struct scsi_cmnd *cmd, u8 reset_cmd)
1da177e4 851{
1b0224b0
OZ
852 struct Scsi_Host *sh = cmd->device->host;
853 struct aha1542_hostdata *aha1542 = shost_priv(sh);
854 unsigned long flags;
1da177e4
LT
855 int i;
856
1b0224b0 857 spin_lock_irqsave(sh->host_lock, flags);
1da177e4
LT
858 /*
859 * This does a scsi reset for all devices on the bus.
860 * In principle, we could also reset the 1542 - should
861 * we do this? Try this first, and we can add that later
862 * if it turns out to be useful.
863 */
55b28f9f 864 outb(reset_cmd, CONTROL(cmd->device->host->io_port));
1da177e4 865
55b28f9f 866 if (!wait_mask(STATUS(cmd->device->host->io_port),
7061dec4 867 STATMASK, IDLE, STST | DIAGF | INVDCMD | DF | CDF, 0)) {
1b0224b0 868 spin_unlock_irqrestore(sh->host_lock, flags);
a13b3722
OZ
869 return FAILED;
870 }
1b0224b0 871
8537cba8
OZ
872 /*
873 * We need to do this too before the 1542 can interact with
874 * us again after host reset.
875 */
876 if (reset_cmd & HRST)
68ea9de3 877 setup_mailboxes(cmd->device->host);
1b0224b0 878
1da177e4
LT
879 /*
880 * Now try to pick up the pieces. For all pending commands,
881 * free any internal data structures, and basically clear things
882 * out. We do not try and restart any commands or anything -
883 * the strategy handler takes care of that crap.
884 */
2906b3ce 885 shost_printk(KERN_WARNING, cmd->device->host, "Sent BUS RESET to scsi host %d\n", cmd->device->host->host_no);
1da177e4
LT
886
887 for (i = 0; i < AHA1542_MAILBOXES; i++) {
55b28f9f
OZ
888 if (aha1542->int_cmds[i] != NULL) {
889 struct scsi_cmnd *tmp_cmd;
890 tmp_cmd = aha1542->int_cmds[i];
1da177e4 891
55b28f9f 892 if (tmp_cmd->device->soft_reset) {
1da177e4
LT
893 /*
894 * If this device implements the soft reset option,
895 * then it is still holding onto the command, and
896 * may yet complete it. In this case, we don't
897 * flush the data.
898 */
899 continue;
900 }
55b28f9f
OZ
901 kfree(tmp_cmd->host_scribble);
902 tmp_cmd->host_scribble = NULL;
903 aha1542->int_cmds[i] = NULL;
e98878f7 904 aha1542->mb[i].status = 0;
1da177e4
LT
905 }
906 }
907
1b0224b0 908 spin_unlock_irqrestore(sh->host_lock, flags);
1da177e4 909 return SUCCESS;
1da177e4
LT
910}
911
55b28f9f 912static int aha1542_bus_reset(struct scsi_cmnd *cmd)
1da177e4 913{
55b28f9f 914 return aha1542_reset(cmd, SCRST);
8537cba8 915}
1da177e4 916
55b28f9f 917static int aha1542_host_reset(struct scsi_cmnd *cmd)
8537cba8 918{
55b28f9f 919 return aha1542_reset(cmd, HRST | SCRST);
1da177e4
LT
920}
921
1da177e4 922static int aha1542_biosparam(struct scsi_device *sdev,
17787a09 923 struct block_device *bdev, sector_t capacity, int geom[])
1da177e4 924{
e98878f7 925 struct aha1542_hostdata *aha1542 = shost_priv(sdev->host);
1da177e4 926
17787a09
OZ
927 if (capacity >= 0x200000 &&
928 aha1542->bios_translation == BIOS_TRANSLATION_25563) {
1da177e4 929 /* Please verify that this is the same as what DOS returns */
17787a09
OZ
930 geom[0] = 255; /* heads */
931 geom[1] = 63; /* sectors */
1da177e4 932 } else {
17787a09
OZ
933 geom[0] = 64; /* heads */
934 geom[1] = 32; /* sectors */
1da177e4 935 }
17787a09 936 geom[2] = sector_div(capacity, geom[0] * geom[1]); /* cylinders */
1da177e4
LT
937
938 return 0;
939}
940MODULE_LICENSE("GPL");
941
d0be4a7d 942static struct scsi_host_template driver_template = {
643a7c43 943 .module = THIS_MODULE,
1da177e4
LT
944 .proc_name = "aha1542",
945 .name = "Adaptec 1542",
1da177e4 946 .queuecommand = aha1542_queuecommand,
1da177e4
LT
947 .eh_device_reset_handler= aha1542_dev_reset,
948 .eh_bus_reset_handler = aha1542_bus_reset,
949 .eh_host_reset_handler = aha1542_host_reset,
950 .bios_param = aha1542_biosparam,
951 .can_queue = AHA1542_MAILBOXES,
952 .this_id = 7,
10be6250
OZ
953 .sg_tablesize = 16,
954 .cmd_per_lun = 1,
1da177e4
LT
955 .unchecked_isa_dma = 1,
956 .use_clustering = ENABLE_CLUSTERING,
957};
643a7c43
OZ
958
959static int aha1542_isa_match(struct device *pdev, unsigned int ndev)
960{
961 struct Scsi_Host *sh = aha1542_hw_init(&driver_template, pdev, ndev);
962
963 if (!sh)
964 return 0;
965
966 dev_set_drvdata(pdev, sh);
967 return 1;
968}
969
970static int aha1542_isa_remove(struct device *pdev,
971 unsigned int ndev)
972{
973 aha1542_release(dev_get_drvdata(pdev));
974 dev_set_drvdata(pdev, NULL);
975 return 0;
976}
977
978static struct isa_driver aha1542_isa_driver = {
979 .match = aha1542_isa_match,
980 .remove = aha1542_isa_remove,
981 .driver = {
982 .name = "aha1542"
983 },
984};
985static int isa_registered;
986
987#ifdef CONFIG_PNP
988static struct pnp_device_id aha1542_pnp_ids[] = {
989 { .id = "ADP1542" },
990 { .id = "" }
991};
992MODULE_DEVICE_TABLE(pnp, aha1542_pnp_ids);
993
994static int aha1542_pnp_probe(struct pnp_dev *pdev, const struct pnp_device_id *id)
995{
996 int indx;
997 struct Scsi_Host *sh;
998
f71429ab
OZ
999 for (indx = 0; indx < ARRAY_SIZE(io); indx++) {
1000 if (io[indx])
643a7c43
OZ
1001 continue;
1002
1003 if (pnp_activate_dev(pdev) < 0)
1004 continue;
1005
f71429ab 1006 io[indx] = pnp_port_start(pdev, 0);
643a7c43
OZ
1007
1008 /* The card can be queried for its DMA, we have
1009 the DMA set up that is enough */
1010
2906b3ce 1011 dev_info(&pdev->dev, "ISAPnP found an AHA1535 at I/O 0x%03X", io[indx]);
643a7c43
OZ
1012 }
1013
1014 sh = aha1542_hw_init(&driver_template, &pdev->dev, indx);
1015 if (!sh)
1016 return -ENODEV;
1017
1018 pnp_set_drvdata(pdev, sh);
1019 return 0;
1020}
1021
1022static void aha1542_pnp_remove(struct pnp_dev *pdev)
1023{
1024 aha1542_release(pnp_get_drvdata(pdev));
1025 pnp_set_drvdata(pdev, NULL);
1026}
1027
1028static struct pnp_driver aha1542_pnp_driver = {
1029 .name = "aha1542",
1030 .id_table = aha1542_pnp_ids,
1031 .probe = aha1542_pnp_probe,
1032 .remove = aha1542_pnp_remove,
1033};
1034static int pnp_registered;
1035#endif /* CONFIG_PNP */
1036
1037static int __init aha1542_init(void)
1038{
1039 int ret = 0;
643a7c43
OZ
1040
1041#ifdef CONFIG_PNP
1042 if (isapnp) {
1043 ret = pnp_register_driver(&aha1542_pnp_driver);
1044 if (!ret)
1045 pnp_registered = 1;
1046 }
1047#endif
1048 ret = isa_register_driver(&aha1542_isa_driver, MAXBOARDS);
1049 if (!ret)
1050 isa_registered = 1;
1051
1052#ifdef CONFIG_PNP
1053 if (pnp_registered)
1054 ret = 0;
1055#endif
1056 if (isa_registered)
1057 ret = 0;
1058
1059 return ret;
1060}
1061
1062static void __exit aha1542_exit(void)
1063{
1064#ifdef CONFIG_PNP
1065 if (pnp_registered)
1066 pnp_unregister_driver(&aha1542_pnp_driver);
1067#endif
1068 if (isa_registered)
1069 isa_unregister_driver(&aha1542_isa_driver);
1070}
1071
1072module_init(aha1542_init);
1073module_exit(aha1542_exit);