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