xref: /linux/drivers/scsi/pcmcia/sym53c500_cs.c (revision 26fbb4c8c7c3ee9a4c3b4de555a8587b5a19154e)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 *  sym53c500_cs.c	Bob Tracy (rct@frus.com)
4 *
5 *  A rewrite of the pcmcia-cs add-on driver for newer (circa 1997)
6 *  New Media Bus Toaster PCMCIA SCSI cards using the Symbios Logic
7 *  53c500 controller: intended for use with 2.6 and later kernels.
8 *  The pcmcia-cs add-on version of this driver is not supported
9 *  beyond 2.4.  It consisted of three files with history/copyright
10 *  information as follows:
11 *
12 *  SYM53C500.h
13 *	Bob Tracy (rct@frus.com)
14 *	Original by Tom Corner (tcorner@via.at).
15 *	Adapted from NCR53c406a.h which is Copyrighted (C) 1994
16 *	Normunds Saumanis (normunds@rx.tech.swh.lv)
17 *
18 *  SYM53C500.c
19 *	Bob Tracy (rct@frus.com)
20 *	Original driver by Tom Corner (tcorner@via.at) was adapted
21 *	from NCR53c406a.c which is Copyrighted (C) 1994, 1995, 1996
22 *	Normunds Saumanis (normunds@fi.ibm.com)
23 *
24 *  sym53c500.c
25 *	Bob Tracy (rct@frus.com)
26 *	Original by Tom Corner (tcorner@via.at) was adapted from a
27 *	driver for the Qlogic SCSI card written by
28 *	David Hinds (dhinds@allegro.stanford.edu).
29 */
30 
31 #define SYM53C500_DEBUG 0
32 #define VERBOSE_SYM53C500_DEBUG 0
33 
34 /*
35 *  Set this to 0 if you encounter kernel lockups while transferring
36 *  data in PIO mode.  Note this can be changed via "sysfs".
37 */
38 #define USE_FAST_PIO 1
39 
40 /* =============== End of user configurable parameters ============== */
41 
42 #include <linux/module.h>
43 #include <linux/moduleparam.h>
44 #include <linux/errno.h>
45 #include <linux/init.h>
46 #include <linux/interrupt.h>
47 #include <linux/kernel.h>
48 #include <linux/slab.h>
49 #include <linux/string.h>
50 #include <linux/ioport.h>
51 #include <linux/blkdev.h>
52 #include <linux/spinlock.h>
53 #include <linux/bitops.h>
54 
55 #include <asm/io.h>
56 #include <asm/dma.h>
57 #include <asm/irq.h>
58 
59 #include <scsi/scsi_ioctl.h>
60 #include <scsi/scsi_cmnd.h>
61 #include <scsi/scsi_device.h>
62 #include <scsi/scsi.h>
63 #include <scsi/scsi_host.h>
64 
65 #include <pcmcia/cistpl.h>
66 #include <pcmcia/ds.h>
67 #include <pcmcia/ciscode.h>
68 
69 
70 /* ================================================================== */
71 
72 #define SYNC_MODE 0 		/* Synchronous transfer mode */
73 
74 /* Default configuration */
75 #define C1_IMG   0x07		/* ID=7 */
76 #define C2_IMG   0x48		/* FE SCSI2 */
77 #define C3_IMG   0x20		/* CDB */
78 #define C4_IMG   0x04		/* ANE */
79 #define C5_IMG   0xa4		/* ? changed from b6= AA PI SIE POL */
80 #define C7_IMG   0x80		/* added for SYM53C500 t. corner */
81 
82 /* Hardware Registers: offsets from io_port (base) */
83 
84 /* Control Register Set 0 */
85 #define TC_LSB		0x00		/* transfer counter lsb */
86 #define TC_MSB		0x01		/* transfer counter msb */
87 #define SCSI_FIFO	0x02		/* scsi fifo register */
88 #define CMD_REG		0x03		/* command register */
89 #define STAT_REG	0x04		/* status register */
90 #define DEST_ID		0x04		/* selection/reselection bus id */
91 #define INT_REG		0x05		/* interrupt status register */
92 #define SRTIMOUT	0x05		/* select/reselect timeout reg */
93 #define SEQ_REG		0x06		/* sequence step register */
94 #define SYNCPRD		0x06		/* synchronous transfer period */
95 #define FIFO_FLAGS	0x07		/* indicates # of bytes in fifo */
96 #define SYNCOFF		0x07		/* synchronous offset register */
97 #define CONFIG1		0x08		/* configuration register */
98 #define CLKCONV		0x09		/* clock conversion register */
99 /* #define TESTREG	0x0A */		/* test mode register */
100 #define CONFIG2		0x0B		/* configuration 2 register */
101 #define CONFIG3		0x0C		/* configuration 3 register */
102 #define CONFIG4		0x0D		/* configuration 4 register */
103 #define TC_HIGH		0x0E		/* transfer counter high */
104 /* #define FIFO_BOTTOM	0x0F */		/* reserve FIFO byte register */
105 
106 /* Control Register Set 1 */
107 /* #define JUMPER_SENSE	0x00 */		/* jumper sense port reg (r/w) */
108 /* #define SRAM_PTR	0x01 */		/* SRAM address pointer reg (r/w) */
109 /* #define SRAM_DATA	0x02 */		/* SRAM data register (r/w) */
110 #define PIO_FIFO	0x04		/* PIO FIFO registers (r/w) */
111 /* #define PIO_FIFO1	0x05 */		/*  */
112 /* #define PIO_FIFO2	0x06 */		/*  */
113 /* #define PIO_FIFO3	0x07 */		/*  */
114 #define PIO_STATUS	0x08		/* PIO status (r/w) */
115 /* #define ATA_CMD	0x09 */		/* ATA command/status reg (r/w) */
116 /* #define ATA_ERR	0x0A */		/* ATA features/error reg (r/w) */
117 #define PIO_FLAG	0x0B		/* PIO flag interrupt enable (r/w) */
118 #define CONFIG5		0x09		/* configuration 5 register */
119 /* #define SIGNATURE	0x0E */		/* signature register (r) */
120 /* #define CONFIG6	0x0F */		/* configuration 6 register (r) */
121 #define CONFIG7		0x0d
122 
123 /* select register set 0 */
124 #define REG0(x)		(outb(C4_IMG, (x) + CONFIG4))
125 /* select register set 1 */
126 #define REG1(x)		outb(C7_IMG, (x) + CONFIG7); outb(C5_IMG, (x) + CONFIG5)
127 
128 #if SYM53C500_DEBUG
129 #define DEB(x) x
130 #else
131 #define DEB(x)
132 #endif
133 
134 #if VERBOSE_SYM53C500_DEBUG
135 #define VDEB(x) x
136 #else
137 #define VDEB(x)
138 #endif
139 
140 #define LOAD_DMA_COUNT(x, count) \
141   outb(count & 0xff, (x) + TC_LSB); \
142   outb((count >> 8) & 0xff, (x) + TC_MSB); \
143   outb((count >> 16) & 0xff, (x) + TC_HIGH);
144 
145 /* Chip commands */
146 #define DMA_OP               0x80
147 
148 #define SCSI_NOP             0x00
149 #define FLUSH_FIFO           0x01
150 #define CHIP_RESET           0x02
151 #define SCSI_RESET           0x03
152 #define RESELECT             0x40
153 #define SELECT_NO_ATN        0x41
154 #define SELECT_ATN           0x42
155 #define SELECT_ATN_STOP      0x43
156 #define ENABLE_SEL           0x44
157 #define DISABLE_SEL          0x45
158 #define SELECT_ATN3          0x46
159 #define RESELECT3            0x47
160 #define TRANSFER_INFO        0x10
161 #define INIT_CMD_COMPLETE    0x11
162 #define MSG_ACCEPT           0x12
163 #define TRANSFER_PAD         0x18
164 #define SET_ATN              0x1a
165 #define RESET_ATN            0x1b
166 #define SEND_MSG             0x20
167 #define SEND_STATUS          0x21
168 #define SEND_DATA            0x22
169 #define DISCONN_SEQ          0x23
170 #define TERMINATE_SEQ        0x24
171 #define TARG_CMD_COMPLETE    0x25
172 #define DISCONN              0x27
173 #define RECV_MSG             0x28
174 #define RECV_CMD             0x29
175 #define RECV_DATA            0x2a
176 #define RECV_CMD_SEQ         0x2b
177 #define TARGET_ABORT_DMA     0x04
178 
179 /* ================================================================== */
180 
181 struct scsi_info_t {
182 	struct pcmcia_device	*p_dev;
183 	struct Scsi_Host *host;
184 	unsigned short manf_id;
185 };
186 
187 /*
188 *  Repository for per-instance host data.
189 */
190 struct sym53c500_data {
191 	struct scsi_cmnd *current_SC;
192 	int fast_pio;
193 };
194 
195 enum Phase {
196     idle,
197     data_out,
198     data_in,
199     command_ph,
200     status_ph,
201     message_out,
202     message_in
203 };
204 
205 /* ================================================================== */
206 
207 static void
208 chip_init(int io_port)
209 {
210 	REG1(io_port);
211 	outb(0x01, io_port + PIO_STATUS);
212 	outb(0x00, io_port + PIO_FLAG);
213 
214 	outb(C4_IMG, io_port + CONFIG4);	/* REG0(io_port); */
215 	outb(C3_IMG, io_port + CONFIG3);
216 	outb(C2_IMG, io_port + CONFIG2);
217 	outb(C1_IMG, io_port + CONFIG1);
218 
219 	outb(0x05, io_port + CLKCONV);	/* clock conversion factor */
220 	outb(0x9C, io_port + SRTIMOUT);	/* Selection timeout */
221 	outb(0x05, io_port + SYNCPRD);	/* Synchronous transfer period */
222 	outb(SYNC_MODE, io_port + SYNCOFF);	/* synchronous mode */
223 }
224 
225 static void
226 SYM53C500_int_host_reset(int io_port)
227 {
228 	outb(C4_IMG, io_port + CONFIG4);	/* REG0(io_port); */
229 	outb(CHIP_RESET, io_port + CMD_REG);
230 	outb(SCSI_NOP, io_port + CMD_REG);	/* required after reset */
231 	outb(SCSI_RESET, io_port + CMD_REG);
232 	chip_init(io_port);
233 }
234 
235 static __inline__ int
236 SYM53C500_pio_read(int fast_pio, int base, unsigned char *request, unsigned int reqlen)
237 {
238 	int i;
239 	int len;	/* current scsi fifo size */
240 
241 	REG1(base);
242 	while (reqlen) {
243 		i = inb(base + PIO_STATUS);
244 		/* VDEB(printk("pio_status=%x\n", i)); */
245 		if (i & 0x80)
246 			return 0;
247 
248 		switch (i & 0x1e) {
249 		default:
250 		case 0x10:	/* fifo empty */
251 			len = 0;
252 			break;
253 		case 0x0:
254 			len = 1;
255 			break;
256 		case 0x8:	/* fifo 1/3 full */
257 			len = 42;
258 			break;
259 		case 0xc:	/* fifo 2/3 full */
260 			len = 84;
261 			break;
262 		case 0xe:	/* fifo full */
263 			len = 128;
264 			break;
265 		}
266 
267 		if ((i & 0x40) && len == 0) { /* fifo empty and interrupt occurred */
268 			return 0;
269 		}
270 
271 		if (len) {
272 			if (len > reqlen)
273 				len = reqlen;
274 
275 			if (fast_pio && len > 3) {
276 				insl(base + PIO_FIFO, request, len >> 2);
277 				request += len & 0xfc;
278 				reqlen -= len & 0xfc;
279 			} else {
280 				while (len--) {
281 					*request++ = inb(base + PIO_FIFO);
282 					reqlen--;
283 				}
284 			}
285 		}
286 	}
287 	return 0;
288 }
289 
290 static __inline__ int
291 SYM53C500_pio_write(int fast_pio, int base, unsigned char *request, unsigned int reqlen)
292 {
293 	int i = 0;
294 	int len;	/* current scsi fifo size */
295 
296 	REG1(base);
297 	while (reqlen && !(i & 0x40)) {
298 		i = inb(base + PIO_STATUS);
299 		/* VDEB(printk("pio_status=%x\n", i)); */
300 		if (i & 0x80)	/* error */
301 			return 0;
302 
303 		switch (i & 0x1e) {
304 		case 0x10:
305 			len = 128;
306 			break;
307 		case 0x0:
308 			len = 84;
309 			break;
310 		case 0x8:
311 			len = 42;
312 			break;
313 		case 0xc:
314 			len = 1;
315 			break;
316 		default:
317 		case 0xe:
318 			len = 0;
319 			break;
320 		}
321 
322 		if (len) {
323 			if (len > reqlen)
324 				len = reqlen;
325 
326 			if (fast_pio && len > 3) {
327 				outsl(base + PIO_FIFO, request, len >> 2);
328 				request += len & 0xfc;
329 				reqlen -= len & 0xfc;
330 			} else {
331 				while (len--) {
332 					outb(*request++, base + PIO_FIFO);
333 					reqlen--;
334 				}
335 			}
336 		}
337 	}
338 	return 0;
339 }
340 
341 static irqreturn_t
342 SYM53C500_intr(int irq, void *dev_id)
343 {
344 	unsigned long flags;
345 	struct Scsi_Host *dev = dev_id;
346 	DEB(unsigned char fifo_size;)
347 	DEB(unsigned char seq_reg;)
348 	unsigned char status, int_reg;
349 	unsigned char pio_status;
350 	int port_base = dev->io_port;
351 	struct sym53c500_data *data =
352 	    (struct sym53c500_data *)dev->hostdata;
353 	struct scsi_cmnd *curSC = data->current_SC;
354 	int fast_pio = data->fast_pio;
355 
356 	spin_lock_irqsave(dev->host_lock, flags);
357 
358 	VDEB(printk("SYM53C500_intr called\n"));
359 
360 	REG1(port_base);
361 	pio_status = inb(port_base + PIO_STATUS);
362 	REG0(port_base);
363 	status = inb(port_base + STAT_REG);
364 	DEB(seq_reg = inb(port_base + SEQ_REG));
365 	int_reg = inb(port_base + INT_REG);
366 	DEB(fifo_size = inb(port_base + FIFO_FLAGS) & 0x1f);
367 
368 #if SYM53C500_DEBUG
369 	printk("status=%02x, seq_reg=%02x, int_reg=%02x, fifo_size=%02x",
370 	    status, seq_reg, int_reg, fifo_size);
371 	printk(", pio=%02x\n", pio_status);
372 #endif /* SYM53C500_DEBUG */
373 
374 	if (int_reg & 0x80) {	/* SCSI reset intr */
375 		DEB(printk("SYM53C500: reset intr received\n"));
376 		curSC->result = DID_RESET << 16;
377 		goto idle_out;
378 	}
379 
380 	if (pio_status & 0x80) {
381 		printk("SYM53C500: Warning: PIO error!\n");
382 		curSC->result = DID_ERROR << 16;
383 		goto idle_out;
384 	}
385 
386 	if (status & 0x20) {		/* Parity error */
387 		printk("SYM53C500: Warning: parity error!\n");
388 		curSC->result = DID_PARITY << 16;
389 		goto idle_out;
390 	}
391 
392 	if (status & 0x40) {		/* Gross error */
393 		printk("SYM53C500: Warning: gross error!\n");
394 		curSC->result = DID_ERROR << 16;
395 		goto idle_out;
396 	}
397 
398 	if (int_reg & 0x20) {		/* Disconnect */
399 		DEB(printk("SYM53C500: disconnect intr received\n"));
400 		if (curSC->SCp.phase != message_in) {	/* Unexpected disconnect */
401 			curSC->result = DID_NO_CONNECT << 16;
402 		} else {	/* Command complete, return status and message */
403 			curSC->result = (curSC->SCp.Status & 0xff)
404 			    | ((curSC->SCp.Message & 0xff) << 8) | (DID_OK << 16);
405 		}
406 		goto idle_out;
407 	}
408 
409 	switch (status & 0x07) {	/* scsi phase */
410 	case 0x00:			/* DATA-OUT */
411 		if (int_reg & 0x10) {	/* Target requesting info transfer */
412 			struct scatterlist *sg;
413 			int i;
414 
415 			curSC->SCp.phase = data_out;
416 			VDEB(printk("SYM53C500: Data-Out phase\n"));
417 			outb(FLUSH_FIFO, port_base + CMD_REG);
418 			LOAD_DMA_COUNT(port_base, scsi_bufflen(curSC));	/* Max transfer size */
419 			outb(TRANSFER_INFO | DMA_OP, port_base + CMD_REG);
420 
421 			scsi_for_each_sg(curSC, sg, scsi_sg_count(curSC), i) {
422 				SYM53C500_pio_write(fast_pio, port_base,
423 				    sg_virt(sg), sg->length);
424 			}
425 			REG0(port_base);
426 		}
427 		break;
428 
429 	case 0x01:		/* DATA-IN */
430 		if (int_reg & 0x10) {	/* Target requesting info transfer */
431 			struct scatterlist *sg;
432 			int i;
433 
434 			curSC->SCp.phase = data_in;
435 			VDEB(printk("SYM53C500: Data-In phase\n"));
436 			outb(FLUSH_FIFO, port_base + CMD_REG);
437 			LOAD_DMA_COUNT(port_base, scsi_bufflen(curSC));	/* Max transfer size */
438 			outb(TRANSFER_INFO | DMA_OP, port_base + CMD_REG);
439 
440 			scsi_for_each_sg(curSC, sg, scsi_sg_count(curSC), i) {
441 				SYM53C500_pio_read(fast_pio, port_base,
442 					sg_virt(sg), sg->length);
443 			}
444 			REG0(port_base);
445 		}
446 		break;
447 
448 	case 0x02:		/* COMMAND */
449 		curSC->SCp.phase = command_ph;
450 		printk("SYM53C500: Warning: Unknown interrupt occurred in command phase!\n");
451 		break;
452 
453 	case 0x03:		/* STATUS */
454 		curSC->SCp.phase = status_ph;
455 		VDEB(printk("SYM53C500: Status phase\n"));
456 		outb(FLUSH_FIFO, port_base + CMD_REG);
457 		outb(INIT_CMD_COMPLETE, port_base + CMD_REG);
458 		break;
459 
460 	case 0x04:		/* Reserved */
461 	case 0x05:		/* Reserved */
462 		printk("SYM53C500: WARNING: Reserved phase!!!\n");
463 		break;
464 
465 	case 0x06:		/* MESSAGE-OUT */
466 		DEB(printk("SYM53C500: Message-Out phase\n"));
467 		curSC->SCp.phase = message_out;
468 		outb(SET_ATN, port_base + CMD_REG);	/* Reject the message */
469 		outb(MSG_ACCEPT, port_base + CMD_REG);
470 		break;
471 
472 	case 0x07:		/* MESSAGE-IN */
473 		VDEB(printk("SYM53C500: Message-In phase\n"));
474 		curSC->SCp.phase = message_in;
475 
476 		curSC->SCp.Status = inb(port_base + SCSI_FIFO);
477 		curSC->SCp.Message = inb(port_base + SCSI_FIFO);
478 
479 		VDEB(printk("SCSI FIFO size=%d\n", inb(port_base + FIFO_FLAGS) & 0x1f));
480 		DEB(printk("Status = %02x  Message = %02x\n", curSC->SCp.Status, curSC->SCp.Message));
481 
482 		if (curSC->SCp.Message == SAVE_POINTERS || curSC->SCp.Message == DISCONNECT) {
483 			outb(SET_ATN, port_base + CMD_REG);	/* Reject message */
484 			DEB(printk("Discarding SAVE_POINTERS message\n"));
485 		}
486 		outb(MSG_ACCEPT, port_base + CMD_REG);
487 		break;
488 	}
489 out:
490 	spin_unlock_irqrestore(dev->host_lock, flags);
491 	return IRQ_HANDLED;
492 
493 idle_out:
494 	curSC->SCp.phase = idle;
495 	curSC->scsi_done(curSC);
496 	goto out;
497 }
498 
499 static void
500 SYM53C500_release(struct pcmcia_device *link)
501 {
502 	struct scsi_info_t *info = link->priv;
503 	struct Scsi_Host *shost = info->host;
504 
505 	dev_dbg(&link->dev, "SYM53C500_release\n");
506 
507 	/*
508 	*  Do this before releasing/freeing resources.
509 	*/
510 	scsi_remove_host(shost);
511 
512 	/*
513 	*  Interrupts getting hosed on card removal.  Try
514 	*  the following code, mostly from qlogicfas.c.
515 	*/
516 	if (shost->irq)
517 		free_irq(shost->irq, shost);
518 	if (shost->io_port && shost->n_io_port)
519 		release_region(shost->io_port, shost->n_io_port);
520 
521 	pcmcia_disable_device(link);
522 
523 	scsi_host_put(shost);
524 } /* SYM53C500_release */
525 
526 static const char*
527 SYM53C500_info(struct Scsi_Host *SChost)
528 {
529 	static char info_msg[256];
530 	struct sym53c500_data *data =
531 	    (struct sym53c500_data *)SChost->hostdata;
532 
533 	DEB(printk("SYM53C500_info called\n"));
534 	(void)snprintf(info_msg, sizeof(info_msg),
535 	    "SYM53C500 at 0x%lx, IRQ %d, %s PIO mode.",
536 	    SChost->io_port, SChost->irq, data->fast_pio ? "fast" : "slow");
537 	return (info_msg);
538 }
539 
540 static int
541 SYM53C500_queue_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
542 {
543 	int i;
544 	int port_base = SCpnt->device->host->io_port;
545 	struct sym53c500_data *data =
546 	    (struct sym53c500_data *)SCpnt->device->host->hostdata;
547 
548 	VDEB(printk("SYM53C500_queue called\n"));
549 
550 	DEB(printk("cmd=%02x, cmd_len=%02x, target=%02x, lun=%02x, bufflen=%d\n",
551 	    SCpnt->cmnd[0], SCpnt->cmd_len, SCpnt->device->id,
552 		   (u8)SCpnt->device->lun,  scsi_bufflen(SCpnt)));
553 
554 	VDEB(for (i = 0; i < SCpnt->cmd_len; i++)
555 	    printk("cmd[%d]=%02x  ", i, SCpnt->cmnd[i]));
556 	VDEB(printk("\n"));
557 
558 	data->current_SC = SCpnt;
559 	data->current_SC->scsi_done = done;
560 	data->current_SC->SCp.phase = command_ph;
561 	data->current_SC->SCp.Status = 0;
562 	data->current_SC->SCp.Message = 0;
563 
564 	/* We are locked here already by the mid layer */
565 	REG0(port_base);
566 	outb(scmd_id(SCpnt), port_base + DEST_ID);	/* set destination */
567 	outb(FLUSH_FIFO, port_base + CMD_REG);	/* reset the fifos */
568 
569 	for (i = 0; i < SCpnt->cmd_len; i++) {
570 		outb(SCpnt->cmnd[i], port_base + SCSI_FIFO);
571 	}
572 	outb(SELECT_NO_ATN, port_base + CMD_REG);
573 
574 	return 0;
575 }
576 
577 static DEF_SCSI_QCMD(SYM53C500_queue)
578 
579 static int
580 SYM53C500_host_reset(struct scsi_cmnd *SCpnt)
581 {
582 	int port_base = SCpnt->device->host->io_port;
583 
584 	DEB(printk("SYM53C500_host_reset called\n"));
585 	spin_lock_irq(SCpnt->device->host->host_lock);
586 	SYM53C500_int_host_reset(port_base);
587 	spin_unlock_irq(SCpnt->device->host->host_lock);
588 
589 	return SUCCESS;
590 }
591 
592 static int
593 SYM53C500_biosparm(struct scsi_device *disk,
594     struct block_device *dev,
595     sector_t capacity, int *info_array)
596 {
597 	int size;
598 
599 	DEB(printk("SYM53C500_biosparm called\n"));
600 
601 	size = capacity;
602 	info_array[0] = 64;		/* heads */
603 	info_array[1] = 32;		/* sectors */
604 	info_array[2] = size >> 11;	/* cylinders */
605 	if (info_array[2] > 1024) {	/* big disk */
606 		info_array[0] = 255;
607 		info_array[1] = 63;
608 		info_array[2] = size / (255 * 63);
609 	}
610 	return 0;
611 }
612 
613 static ssize_t
614 SYM53C500_show_pio(struct device *dev, struct device_attribute *attr,
615 		   char *buf)
616 {
617 	struct Scsi_Host *SHp = class_to_shost(dev);
618 	struct sym53c500_data *data =
619 	    (struct sym53c500_data *)SHp->hostdata;
620 
621 	return snprintf(buf, 4, "%d\n", data->fast_pio);
622 }
623 
624 static ssize_t
625 SYM53C500_store_pio(struct device *dev, struct device_attribute *attr,
626 		    const char *buf, size_t count)
627 {
628 	int pio;
629 	struct Scsi_Host *SHp = class_to_shost(dev);
630 	struct sym53c500_data *data =
631 	    (struct sym53c500_data *)SHp->hostdata;
632 
633 	pio = simple_strtoul(buf, NULL, 0);
634 	if (pio == 0 || pio == 1) {
635 		data->fast_pio = pio;
636 		return count;
637 	}
638 	else
639 		return -EINVAL;
640 }
641 
642 /*
643 *  SCSI HBA device attributes we want to
644 *  make available via sysfs.
645 */
646 static struct device_attribute SYM53C500_pio_attr = {
647 	.attr = {
648 		.name = "fast_pio",
649 		.mode = (S_IRUGO | S_IWUSR),
650 	},
651 	.show = SYM53C500_show_pio,
652 	.store = SYM53C500_store_pio,
653 };
654 
655 static struct device_attribute *SYM53C500_shost_attrs[] = {
656 	&SYM53C500_pio_attr,
657 	NULL,
658 };
659 
660 /*
661 *  scsi_host_template initializer
662 */
663 static struct scsi_host_template sym53c500_driver_template = {
664      .module			= THIS_MODULE,
665      .name			= "SYM53C500",
666      .info			= SYM53C500_info,
667      .queuecommand		= SYM53C500_queue,
668      .eh_host_reset_handler	= SYM53C500_host_reset,
669      .bios_param		= SYM53C500_biosparm,
670      .proc_name			= "SYM53C500",
671      .can_queue			= 1,
672      .this_id			= 7,
673      .sg_tablesize		= 32,
674      .shost_attrs		= SYM53C500_shost_attrs
675 };
676 
677 static int SYM53C500_config_check(struct pcmcia_device *p_dev, void *priv_data)
678 {
679 	p_dev->io_lines = 10;
680 	p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
681 	p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
682 
683 	if (p_dev->resource[0]->start == 0)
684 		return -ENODEV;
685 
686 	return pcmcia_request_io(p_dev);
687 }
688 
689 static int
690 SYM53C500_config(struct pcmcia_device *link)
691 {
692 	struct scsi_info_t *info = link->priv;
693 	int ret;
694 	int irq_level, port_base;
695 	struct Scsi_Host *host;
696 	struct scsi_host_template *tpnt = &sym53c500_driver_template;
697 	struct sym53c500_data *data;
698 
699 	dev_dbg(&link->dev, "SYM53C500_config\n");
700 
701 	info->manf_id = link->manf_id;
702 
703 	ret = pcmcia_loop_config(link, SYM53C500_config_check, NULL);
704 	if (ret)
705 		goto failed;
706 
707 	if (!link->irq)
708 		goto failed;
709 
710 	ret = pcmcia_enable_device(link);
711 	if (ret)
712 		goto failed;
713 
714 	/*
715 	*  That's the trouble with copying liberally from another driver.
716 	*  Some things probably aren't relevant, and I suspect this entire
717 	*  section dealing with manufacturer IDs can be scrapped.	--rct
718 	*/
719 	if ((info->manf_id == MANFID_MACNICA) ||
720 	    (info->manf_id == MANFID_PIONEER) ||
721 	    (info->manf_id == 0x0098)) {
722 		/* set ATAcmd */
723 		outb(0xb4, link->resource[0]->start + 0xd);
724 		outb(0x24, link->resource[0]->start + 0x9);
725 		outb(0x04, link->resource[0]->start + 0xd);
726 	}
727 
728 	/*
729 	*  irq_level == 0 implies tpnt->can_queue == 0, which
730 	*  is not supported in 2.6.  Thus, only irq_level > 0
731 	*  will be allowed.
732 	*
733 	*  Possible port_base values are as follows:
734 	*
735 	*	0x130, 0x230, 0x280, 0x290,
736 	*	0x320, 0x330, 0x340, 0x350
737 	*/
738 	port_base = link->resource[0]->start;
739 	irq_level = link->irq;
740 
741 	DEB(printk("SYM53C500: port_base=0x%x, irq=%d, fast_pio=%d\n",
742 	    port_base, irq_level, USE_FAST_PIO);)
743 
744 	chip_init(port_base);
745 
746 	host = scsi_host_alloc(tpnt, sizeof(struct sym53c500_data));
747 	if (!host) {
748 		printk("SYM53C500: Unable to register host, giving up.\n");
749 		goto err_release;
750 	}
751 
752 	data = (struct sym53c500_data *)host->hostdata;
753 
754 	if (irq_level > 0) {
755 		if (request_irq(irq_level, SYM53C500_intr, IRQF_SHARED, "SYM53C500", host)) {
756 			printk("SYM53C500: unable to allocate IRQ %d\n", irq_level);
757 			goto err_free_scsi;
758 		}
759 		DEB(printk("SYM53C500: allocated IRQ %d\n", irq_level));
760 	} else if (irq_level == 0) {
761 		DEB(printk("SYM53C500: No interrupts detected\n"));
762 		goto err_free_scsi;
763 	} else {
764 		DEB(printk("SYM53C500: Shouldn't get here!\n"));
765 		goto err_free_scsi;
766 	}
767 
768 	host->unique_id = port_base;
769 	host->irq = irq_level;
770 	host->io_port = port_base;
771 	host->n_io_port = 0x10;
772 	host->dma_channel = -1;
773 
774 	/*
775 	*  Note fast_pio is set to USE_FAST_PIO by
776 	*  default, but can be changed via "sysfs".
777 	*/
778 	data->fast_pio = USE_FAST_PIO;
779 
780 	info->host = host;
781 
782 	if (scsi_add_host(host, NULL))
783 		goto err_free_irq;
784 
785 	scsi_scan_host(host);
786 
787 	return 0;
788 
789 err_free_irq:
790 	free_irq(irq_level, host);
791 err_free_scsi:
792 	scsi_host_put(host);
793 err_release:
794 	release_region(port_base, 0x10);
795 	printk(KERN_INFO "sym53c500_cs: no SCSI devices found\n");
796 	return -ENODEV;
797 
798 failed:
799 	SYM53C500_release(link);
800 	return -ENODEV;
801 } /* SYM53C500_config */
802 
803 static int sym53c500_resume(struct pcmcia_device *link)
804 {
805 	struct scsi_info_t *info = link->priv;
806 
807 	/* See earlier comment about manufacturer IDs. */
808 	if ((info->manf_id == MANFID_MACNICA) ||
809 	    (info->manf_id == MANFID_PIONEER) ||
810 	    (info->manf_id == 0x0098)) {
811 		outb(0x80, link->resource[0]->start + 0xd);
812 		outb(0x24, link->resource[0]->start + 0x9);
813 		outb(0x04, link->resource[0]->start + 0xd);
814 	}
815 	/*
816 	 *  If things don't work after a "resume",
817 	 *  this is a good place to start looking.
818 	 */
819 	SYM53C500_int_host_reset(link->resource[0]->start);
820 
821 	return 0;
822 }
823 
824 static void
825 SYM53C500_detach(struct pcmcia_device *link)
826 {
827 	dev_dbg(&link->dev, "SYM53C500_detach\n");
828 
829 	SYM53C500_release(link);
830 
831 	kfree(link->priv);
832 	link->priv = NULL;
833 } /* SYM53C500_detach */
834 
835 static int
836 SYM53C500_probe(struct pcmcia_device *link)
837 {
838 	struct scsi_info_t *info;
839 
840 	dev_dbg(&link->dev, "SYM53C500_attach()\n");
841 
842 	/* Create new SCSI device */
843 	info = kzalloc(sizeof(*info), GFP_KERNEL);
844 	if (!info)
845 		return -ENOMEM;
846 	info->p_dev = link;
847 	link->priv = info;
848 	link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
849 
850 	return SYM53C500_config(link);
851 } /* SYM53C500_attach */
852 
853 MODULE_AUTHOR("Bob Tracy <rct@frus.com>");
854 MODULE_DESCRIPTION("SYM53C500 PCMCIA SCSI driver");
855 MODULE_LICENSE("GPL");
856 
857 static const struct pcmcia_device_id sym53c500_ids[] = {
858 	PCMCIA_DEVICE_PROD_ID12("BASICS by New Media Corporation", "SCSI Sym53C500", 0x23c78a9d, 0x0099e7f7),
859 	PCMCIA_DEVICE_PROD_ID12("New Media Corporation", "SCSI Bus Toaster Sym53C500", 0x085a850b, 0x45432eb8),
860 	PCMCIA_DEVICE_PROD_ID2("SCSI9000", 0x21648f44),
861 	PCMCIA_DEVICE_NULL,
862 };
863 MODULE_DEVICE_TABLE(pcmcia, sym53c500_ids);
864 
865 static struct pcmcia_driver sym53c500_cs_driver = {
866 	.owner		= THIS_MODULE,
867 	.name		= "sym53c500_cs",
868 	.probe		= SYM53C500_probe,
869 	.remove		= SYM53C500_detach,
870 	.id_table       = sym53c500_ids,
871 	.resume		= sym53c500_resume,
872 };
873 module_pcmcia_driver(sym53c500_cs_driver);
874