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