0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031 #define SYM53C500_DEBUG 0
0032 #define VERBOSE_SYM53C500_DEBUG 0
0033
0034
0035
0036
0037
0038 #define USE_FAST_PIO 1
0039
0040
0041
0042 #include <linux/module.h>
0043 #include <linux/moduleparam.h>
0044 #include <linux/errno.h>
0045 #include <linux/init.h>
0046 #include <linux/interrupt.h>
0047 #include <linux/kernel.h>
0048 #include <linux/slab.h>
0049 #include <linux/string.h>
0050 #include <linux/ioport.h>
0051 #include <linux/blkdev.h>
0052 #include <linux/spinlock.h>
0053 #include <linux/bitops.h>
0054
0055 #include <asm/io.h>
0056 #include <asm/dma.h>
0057 #include <asm/irq.h>
0058
0059 #include <scsi/scsi_ioctl.h>
0060 #include <scsi/scsi_cmnd.h>
0061 #include <scsi/scsi_device.h>
0062 #include <scsi/scsi.h>
0063 #include <scsi/scsi_host.h>
0064
0065 #include <pcmcia/cistpl.h>
0066 #include <pcmcia/ds.h>
0067 #include <pcmcia/ciscode.h>
0068
0069
0070
0071
0072 #define SYNC_MODE 0
0073
0074
0075 #define C1_IMG 0x07
0076 #define C2_IMG 0x48
0077 #define C3_IMG 0x20
0078 #define C4_IMG 0x04
0079 #define C5_IMG 0xa4
0080 #define C7_IMG 0x80
0081
0082
0083
0084
0085 #define TC_LSB 0x00
0086 #define TC_MSB 0x01
0087 #define SCSI_FIFO 0x02
0088 #define CMD_REG 0x03
0089 #define STAT_REG 0x04
0090 #define DEST_ID 0x04
0091 #define INT_REG 0x05
0092 #define SRTIMOUT 0x05
0093 #define SEQ_REG 0x06
0094 #define SYNCPRD 0x06
0095 #define FIFO_FLAGS 0x07
0096 #define SYNCOFF 0x07
0097 #define CONFIG1 0x08
0098 #define CLKCONV 0x09
0099
0100 #define CONFIG2 0x0B
0101 #define CONFIG3 0x0C
0102 #define CONFIG4 0x0D
0103 #define TC_HIGH 0x0E
0104
0105
0106
0107
0108
0109
0110 #define PIO_FIFO 0x04
0111
0112
0113
0114 #define PIO_STATUS 0x08
0115
0116
0117 #define PIO_FLAG 0x0B
0118 #define CONFIG5 0x09
0119
0120
0121 #define CONFIG7 0x0d
0122
0123
0124 #define REG0(x) (outb(C4_IMG, (x) + CONFIG4))
0125
0126 #define REG1(x) outb(C7_IMG, (x) + CONFIG7); outb(C5_IMG, (x) + CONFIG5)
0127
0128 #if SYM53C500_DEBUG
0129 #define DEB(x) x
0130 #else
0131 #define DEB(x)
0132 #endif
0133
0134 #if VERBOSE_SYM53C500_DEBUG
0135 #define VDEB(x) x
0136 #else
0137 #define VDEB(x)
0138 #endif
0139
0140 #define LOAD_DMA_COUNT(x, count) \
0141 outb(count & 0xff, (x) + TC_LSB); \
0142 outb((count >> 8) & 0xff, (x) + TC_MSB); \
0143 outb((count >> 16) & 0xff, (x) + TC_HIGH);
0144
0145
0146 #define DMA_OP 0x80
0147
0148 #define SCSI_NOP 0x00
0149 #define FLUSH_FIFO 0x01
0150 #define CHIP_RESET 0x02
0151 #define SCSI_RESET 0x03
0152 #define RESELECT 0x40
0153 #define SELECT_NO_ATN 0x41
0154 #define SELECT_ATN 0x42
0155 #define SELECT_ATN_STOP 0x43
0156 #define ENABLE_SEL 0x44
0157 #define DISABLE_SEL 0x45
0158 #define SELECT_ATN3 0x46
0159 #define RESELECT3 0x47
0160 #define TRANSFER_INFO 0x10
0161 #define INIT_CMD_COMPLETE 0x11
0162 #define MSG_ACCEPT 0x12
0163 #define TRANSFER_PAD 0x18
0164 #define SET_ATN 0x1a
0165 #define RESET_ATN 0x1b
0166 #define SEND_MSG 0x20
0167 #define SEND_STATUS 0x21
0168 #define SEND_DATA 0x22
0169 #define DISCONN_SEQ 0x23
0170 #define TERMINATE_SEQ 0x24
0171 #define TARG_CMD_COMPLETE 0x25
0172 #define DISCONN 0x27
0173 #define RECV_MSG 0x28
0174 #define RECV_CMD 0x29
0175 #define RECV_DATA 0x2a
0176 #define RECV_CMD_SEQ 0x2b
0177 #define TARGET_ABORT_DMA 0x04
0178
0179
0180
0181 struct scsi_info_t {
0182 struct pcmcia_device *p_dev;
0183 struct Scsi_Host *host;
0184 unsigned short manf_id;
0185 };
0186
0187
0188
0189
0190 struct sym53c500_data {
0191 struct scsi_cmnd *current_SC;
0192 int fast_pio;
0193 };
0194
0195 struct sym53c500_cmd_priv {
0196 int status;
0197 int message;
0198 int phase;
0199 };
0200
0201 enum Phase {
0202 idle,
0203 data_out,
0204 data_in,
0205 command_ph,
0206 status_ph,
0207 message_out,
0208 message_in
0209 };
0210
0211
0212
0213 static void
0214 chip_init(int io_port)
0215 {
0216 REG1(io_port);
0217 outb(0x01, io_port + PIO_STATUS);
0218 outb(0x00, io_port + PIO_FLAG);
0219
0220 outb(C4_IMG, io_port + CONFIG4);
0221 outb(C3_IMG, io_port + CONFIG3);
0222 outb(C2_IMG, io_port + CONFIG2);
0223 outb(C1_IMG, io_port + CONFIG1);
0224
0225 outb(0x05, io_port + CLKCONV);
0226 outb(0x9C, io_port + SRTIMOUT);
0227 outb(0x05, io_port + SYNCPRD);
0228 outb(SYNC_MODE, io_port + SYNCOFF);
0229 }
0230
0231 static void
0232 SYM53C500_int_host_reset(int io_port)
0233 {
0234 outb(C4_IMG, io_port + CONFIG4);
0235 outb(CHIP_RESET, io_port + CMD_REG);
0236 outb(SCSI_NOP, io_port + CMD_REG);
0237 outb(SCSI_RESET, io_port + CMD_REG);
0238 chip_init(io_port);
0239 }
0240
0241 static __inline__ int
0242 SYM53C500_pio_read(int fast_pio, int base, unsigned char *request, unsigned int reqlen)
0243 {
0244 int i;
0245 int len;
0246
0247 REG1(base);
0248 while (reqlen) {
0249 i = inb(base + PIO_STATUS);
0250
0251 if (i & 0x80)
0252 return 0;
0253
0254 switch (i & 0x1e) {
0255 default:
0256 case 0x10:
0257 len = 0;
0258 break;
0259 case 0x0:
0260 len = 1;
0261 break;
0262 case 0x8:
0263 len = 42;
0264 break;
0265 case 0xc:
0266 len = 84;
0267 break;
0268 case 0xe:
0269 len = 128;
0270 break;
0271 }
0272
0273 if ((i & 0x40) && len == 0) {
0274 return 0;
0275 }
0276
0277 if (len) {
0278 if (len > reqlen)
0279 len = reqlen;
0280
0281 if (fast_pio && len > 3) {
0282 insl(base + PIO_FIFO, request, len >> 2);
0283 request += len & 0xfc;
0284 reqlen -= len & 0xfc;
0285 } else {
0286 while (len--) {
0287 *request++ = inb(base + PIO_FIFO);
0288 reqlen--;
0289 }
0290 }
0291 }
0292 }
0293 return 0;
0294 }
0295
0296 static __inline__ int
0297 SYM53C500_pio_write(int fast_pio, int base, unsigned char *request, unsigned int reqlen)
0298 {
0299 int i = 0;
0300 int len;
0301
0302 REG1(base);
0303 while (reqlen && !(i & 0x40)) {
0304 i = inb(base + PIO_STATUS);
0305
0306 if (i & 0x80)
0307 return 0;
0308
0309 switch (i & 0x1e) {
0310 case 0x10:
0311 len = 128;
0312 break;
0313 case 0x0:
0314 len = 84;
0315 break;
0316 case 0x8:
0317 len = 42;
0318 break;
0319 case 0xc:
0320 len = 1;
0321 break;
0322 default:
0323 case 0xe:
0324 len = 0;
0325 break;
0326 }
0327
0328 if (len) {
0329 if (len > reqlen)
0330 len = reqlen;
0331
0332 if (fast_pio && len > 3) {
0333 outsl(base + PIO_FIFO, request, len >> 2);
0334 request += len & 0xfc;
0335 reqlen -= len & 0xfc;
0336 } else {
0337 while (len--) {
0338 outb(*request++, base + PIO_FIFO);
0339 reqlen--;
0340 }
0341 }
0342 }
0343 }
0344 return 0;
0345 }
0346
0347 static irqreturn_t
0348 SYM53C500_intr(int irq, void *dev_id)
0349 {
0350 unsigned long flags;
0351 struct Scsi_Host *dev = dev_id;
0352 DEB(unsigned char fifo_size;)
0353 DEB(unsigned char seq_reg;)
0354 unsigned char status, int_reg;
0355 unsigned char pio_status;
0356 int port_base = dev->io_port;
0357 struct sym53c500_data *data =
0358 (struct sym53c500_data *)dev->hostdata;
0359 struct scsi_cmnd *curSC = data->current_SC;
0360 struct sym53c500_cmd_priv *scp = scsi_cmd_priv(curSC);
0361 int fast_pio = data->fast_pio;
0362
0363 spin_lock_irqsave(dev->host_lock, flags);
0364
0365 VDEB(printk("SYM53C500_intr called\n"));
0366
0367 REG1(port_base);
0368 pio_status = inb(port_base + PIO_STATUS);
0369 REG0(port_base);
0370 status = inb(port_base + STAT_REG);
0371 DEB(seq_reg = inb(port_base + SEQ_REG));
0372 int_reg = inb(port_base + INT_REG);
0373 DEB(fifo_size = inb(port_base + FIFO_FLAGS) & 0x1f);
0374
0375 #if SYM53C500_DEBUG
0376 printk("status=%02x, seq_reg=%02x, int_reg=%02x, fifo_size=%02x",
0377 status, seq_reg, int_reg, fifo_size);
0378 printk(", pio=%02x\n", pio_status);
0379 #endif
0380
0381 if (int_reg & 0x80) {
0382 DEB(printk("SYM53C500: reset intr received\n"));
0383 curSC->result = DID_RESET << 16;
0384 goto idle_out;
0385 }
0386
0387 if (pio_status & 0x80) {
0388 printk("SYM53C500: Warning: PIO error!\n");
0389 curSC->result = DID_ERROR << 16;
0390 goto idle_out;
0391 }
0392
0393 if (status & 0x20) {
0394 printk("SYM53C500: Warning: parity error!\n");
0395 curSC->result = DID_PARITY << 16;
0396 goto idle_out;
0397 }
0398
0399 if (status & 0x40) {
0400 printk("SYM53C500: Warning: gross error!\n");
0401 curSC->result = DID_ERROR << 16;
0402 goto idle_out;
0403 }
0404
0405 if (int_reg & 0x20) {
0406 DEB(printk("SYM53C500: disconnect intr received\n"));
0407 if (scp->phase != message_in) {
0408 curSC->result = DID_NO_CONNECT << 16;
0409 } else {
0410 curSC->result = (scp->status & 0xff) |
0411 ((scp->message & 0xff) << 8) | (DID_OK << 16);
0412 }
0413 goto idle_out;
0414 }
0415
0416 switch (status & 0x07) {
0417 case 0x00:
0418 if (int_reg & 0x10) {
0419 struct scatterlist *sg;
0420 int i;
0421
0422 scp->phase = data_out;
0423 VDEB(printk("SYM53C500: Data-Out phase\n"));
0424 outb(FLUSH_FIFO, port_base + CMD_REG);
0425 LOAD_DMA_COUNT(port_base, scsi_bufflen(curSC));
0426 outb(TRANSFER_INFO | DMA_OP, port_base + CMD_REG);
0427
0428 scsi_for_each_sg(curSC, sg, scsi_sg_count(curSC), i) {
0429 SYM53C500_pio_write(fast_pio, port_base,
0430 sg_virt(sg), sg->length);
0431 }
0432 REG0(port_base);
0433 }
0434 break;
0435
0436 case 0x01:
0437 if (int_reg & 0x10) {
0438 struct scatterlist *sg;
0439 int i;
0440
0441 scp->phase = data_in;
0442 VDEB(printk("SYM53C500: Data-In phase\n"));
0443 outb(FLUSH_FIFO, port_base + CMD_REG);
0444 LOAD_DMA_COUNT(port_base, scsi_bufflen(curSC));
0445 outb(TRANSFER_INFO | DMA_OP, port_base + CMD_REG);
0446
0447 scsi_for_each_sg(curSC, sg, scsi_sg_count(curSC), i) {
0448 SYM53C500_pio_read(fast_pio, port_base,
0449 sg_virt(sg), sg->length);
0450 }
0451 REG0(port_base);
0452 }
0453 break;
0454
0455 case 0x02:
0456 scp->phase = command_ph;
0457 printk("SYM53C500: Warning: Unknown interrupt occurred in command phase!\n");
0458 break;
0459
0460 case 0x03:
0461 scp->phase = status_ph;
0462 VDEB(printk("SYM53C500: Status phase\n"));
0463 outb(FLUSH_FIFO, port_base + CMD_REG);
0464 outb(INIT_CMD_COMPLETE, port_base + CMD_REG);
0465 break;
0466
0467 case 0x04:
0468 case 0x05:
0469 printk("SYM53C500: WARNING: Reserved phase!!!\n");
0470 break;
0471
0472 case 0x06:
0473 DEB(printk("SYM53C500: Message-Out phase\n"));
0474 scp->phase = message_out;
0475 outb(SET_ATN, port_base + CMD_REG);
0476 outb(MSG_ACCEPT, port_base + CMD_REG);
0477 break;
0478
0479 case 0x07:
0480 VDEB(printk("SYM53C500: Message-In phase\n"));
0481 scp->phase = message_in;
0482
0483 scp->status = inb(port_base + SCSI_FIFO);
0484 scp->message = inb(port_base + SCSI_FIFO);
0485
0486 VDEB(printk("SCSI FIFO size=%d\n", inb(port_base + FIFO_FLAGS) & 0x1f));
0487 DEB(printk("Status = %02x Message = %02x\n", scp->status, scp->message));
0488
0489 if (scp->message == SAVE_POINTERS || scp->message == DISCONNECT) {
0490 outb(SET_ATN, port_base + CMD_REG);
0491 DEB(printk("Discarding SAVE_POINTERS message\n"));
0492 }
0493 outb(MSG_ACCEPT, port_base + CMD_REG);
0494 break;
0495 }
0496 out:
0497 spin_unlock_irqrestore(dev->host_lock, flags);
0498 return IRQ_HANDLED;
0499
0500 idle_out:
0501 scp->phase = idle;
0502 scsi_done(curSC);
0503 goto out;
0504 }
0505
0506 static void
0507 SYM53C500_release(struct pcmcia_device *link)
0508 {
0509 struct scsi_info_t *info = link->priv;
0510 struct Scsi_Host *shost = info->host;
0511
0512 dev_dbg(&link->dev, "SYM53C500_release\n");
0513
0514
0515
0516
0517 scsi_remove_host(shost);
0518
0519
0520
0521
0522
0523 if (shost->irq)
0524 free_irq(shost->irq, shost);
0525 if (shost->io_port && shost->n_io_port)
0526 release_region(shost->io_port, shost->n_io_port);
0527
0528 pcmcia_disable_device(link);
0529
0530 scsi_host_put(shost);
0531 }
0532
0533 static const char*
0534 SYM53C500_info(struct Scsi_Host *SChost)
0535 {
0536 static char info_msg[256];
0537 struct sym53c500_data *data =
0538 (struct sym53c500_data *)SChost->hostdata;
0539
0540 DEB(printk("SYM53C500_info called\n"));
0541 (void)snprintf(info_msg, sizeof(info_msg),
0542 "SYM53C500 at 0x%lx, IRQ %d, %s PIO mode.",
0543 SChost->io_port, SChost->irq, data->fast_pio ? "fast" : "slow");
0544 return (info_msg);
0545 }
0546
0547 static int SYM53C500_queue_lck(struct scsi_cmnd *SCpnt)
0548 {
0549 struct sym53c500_cmd_priv *scp = scsi_cmd_priv(SCpnt);
0550 int i;
0551 int port_base = SCpnt->device->host->io_port;
0552 struct sym53c500_data *data =
0553 (struct sym53c500_data *)SCpnt->device->host->hostdata;
0554
0555 VDEB(printk("SYM53C500_queue called\n"));
0556
0557 DEB(printk("cmd=%02x, cmd_len=%02x, target=%02x, lun=%02x, bufflen=%d\n",
0558 SCpnt->cmnd[0], SCpnt->cmd_len, SCpnt->device->id,
0559 (u8)SCpnt->device->lun, scsi_bufflen(SCpnt)));
0560
0561 VDEB(for (i = 0; i < SCpnt->cmd_len; i++)
0562 printk("cmd[%d]=%02x ", i, SCpnt->cmnd[i]));
0563 VDEB(printk("\n"));
0564
0565 data->current_SC = SCpnt;
0566 scp->phase = command_ph;
0567 scp->status = 0;
0568 scp->message = 0;
0569
0570
0571 REG0(port_base);
0572 outb(scmd_id(SCpnt), port_base + DEST_ID);
0573 outb(FLUSH_FIFO, port_base + CMD_REG);
0574
0575 for (i = 0; i < SCpnt->cmd_len; i++) {
0576 outb(SCpnt->cmnd[i], port_base + SCSI_FIFO);
0577 }
0578 outb(SELECT_NO_ATN, port_base + CMD_REG);
0579
0580 return 0;
0581 }
0582
0583 static DEF_SCSI_QCMD(SYM53C500_queue)
0584
0585 static int
0586 SYM53C500_host_reset(struct scsi_cmnd *SCpnt)
0587 {
0588 int port_base = SCpnt->device->host->io_port;
0589
0590 DEB(printk("SYM53C500_host_reset called\n"));
0591 spin_lock_irq(SCpnt->device->host->host_lock);
0592 SYM53C500_int_host_reset(port_base);
0593 spin_unlock_irq(SCpnt->device->host->host_lock);
0594
0595 return SUCCESS;
0596 }
0597
0598 static int
0599 SYM53C500_biosparm(struct scsi_device *disk,
0600 struct block_device *dev,
0601 sector_t capacity, int *info_array)
0602 {
0603 int size;
0604
0605 DEB(printk("SYM53C500_biosparm called\n"));
0606
0607 size = capacity;
0608 info_array[0] = 64;
0609 info_array[1] = 32;
0610 info_array[2] = size >> 11;
0611 if (info_array[2] > 1024) {
0612 info_array[0] = 255;
0613 info_array[1] = 63;
0614 info_array[2] = size / (255 * 63);
0615 }
0616 return 0;
0617 }
0618
0619 static ssize_t
0620 SYM53C500_show_pio(struct device *dev, struct device_attribute *attr,
0621 char *buf)
0622 {
0623 struct Scsi_Host *SHp = class_to_shost(dev);
0624 struct sym53c500_data *data =
0625 (struct sym53c500_data *)SHp->hostdata;
0626
0627 return snprintf(buf, 4, "%d\n", data->fast_pio);
0628 }
0629
0630 static ssize_t
0631 SYM53C500_store_pio(struct device *dev, struct device_attribute *attr,
0632 const char *buf, size_t count)
0633 {
0634 int pio;
0635 struct Scsi_Host *SHp = class_to_shost(dev);
0636 struct sym53c500_data *data =
0637 (struct sym53c500_data *)SHp->hostdata;
0638
0639 pio = simple_strtoul(buf, NULL, 0);
0640 if (pio == 0 || pio == 1) {
0641 data->fast_pio = pio;
0642 return count;
0643 }
0644 else
0645 return -EINVAL;
0646 }
0647
0648
0649
0650
0651
0652 static struct device_attribute SYM53C500_pio_attr = {
0653 .attr = {
0654 .name = "fast_pio",
0655 .mode = (S_IRUGO | S_IWUSR),
0656 },
0657 .show = SYM53C500_show_pio,
0658 .store = SYM53C500_store_pio,
0659 };
0660
0661 static struct attribute *SYM53C500_shost_attrs[] = {
0662 &SYM53C500_pio_attr.attr,
0663 NULL,
0664 };
0665
0666 ATTRIBUTE_GROUPS(SYM53C500_shost);
0667
0668
0669
0670
0671 static struct scsi_host_template sym53c500_driver_template = {
0672 .module = THIS_MODULE,
0673 .name = "SYM53C500",
0674 .info = SYM53C500_info,
0675 .queuecommand = SYM53C500_queue,
0676 .eh_host_reset_handler = SYM53C500_host_reset,
0677 .bios_param = SYM53C500_biosparm,
0678 .proc_name = "SYM53C500",
0679 .can_queue = 1,
0680 .this_id = 7,
0681 .sg_tablesize = 32,
0682 .shost_groups = SYM53C500_shost_groups,
0683 .cmd_size = sizeof(struct sym53c500_cmd_priv),
0684 };
0685
0686 static int SYM53C500_config_check(struct pcmcia_device *p_dev, void *priv_data)
0687 {
0688 p_dev->io_lines = 10;
0689 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
0690 p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
0691
0692 if (p_dev->resource[0]->start == 0)
0693 return -ENODEV;
0694
0695 return pcmcia_request_io(p_dev);
0696 }
0697
0698 static int
0699 SYM53C500_config(struct pcmcia_device *link)
0700 {
0701 struct scsi_info_t *info = link->priv;
0702 int ret;
0703 int irq_level, port_base;
0704 struct Scsi_Host *host;
0705 struct scsi_host_template *tpnt = &sym53c500_driver_template;
0706 struct sym53c500_data *data;
0707
0708 dev_dbg(&link->dev, "SYM53C500_config\n");
0709
0710 info->manf_id = link->manf_id;
0711
0712 ret = pcmcia_loop_config(link, SYM53C500_config_check, NULL);
0713 if (ret)
0714 goto failed;
0715
0716 if (!link->irq)
0717 goto failed;
0718
0719 ret = pcmcia_enable_device(link);
0720 if (ret)
0721 goto failed;
0722
0723
0724
0725
0726
0727
0728 if ((info->manf_id == MANFID_MACNICA) ||
0729 (info->manf_id == MANFID_PIONEER) ||
0730 (info->manf_id == 0x0098)) {
0731
0732 outb(0xb4, link->resource[0]->start + 0xd);
0733 outb(0x24, link->resource[0]->start + 0x9);
0734 outb(0x04, link->resource[0]->start + 0xd);
0735 }
0736
0737
0738
0739
0740
0741
0742
0743
0744
0745
0746
0747 port_base = link->resource[0]->start;
0748 irq_level = link->irq;
0749
0750 DEB(printk("SYM53C500: port_base=0x%x, irq=%d, fast_pio=%d\n",
0751 port_base, irq_level, USE_FAST_PIO);)
0752
0753 chip_init(port_base);
0754
0755 host = scsi_host_alloc(tpnt, sizeof(struct sym53c500_data));
0756 if (!host) {
0757 printk("SYM53C500: Unable to register host, giving up.\n");
0758 goto err_release;
0759 }
0760
0761 data = (struct sym53c500_data *)host->hostdata;
0762
0763 if (irq_level > 0) {
0764 if (request_irq(irq_level, SYM53C500_intr, IRQF_SHARED, "SYM53C500", host)) {
0765 printk("SYM53C500: unable to allocate IRQ %d\n", irq_level);
0766 goto err_free_scsi;
0767 }
0768 DEB(printk("SYM53C500: allocated IRQ %d\n", irq_level));
0769 } else if (irq_level == 0) {
0770 DEB(printk("SYM53C500: No interrupts detected\n"));
0771 goto err_free_scsi;
0772 } else {
0773 DEB(printk("SYM53C500: Shouldn't get here!\n"));
0774 goto err_free_scsi;
0775 }
0776
0777 host->unique_id = port_base;
0778 host->irq = irq_level;
0779 host->io_port = port_base;
0780 host->n_io_port = 0x10;
0781 host->dma_channel = -1;
0782
0783
0784
0785
0786
0787 data->fast_pio = USE_FAST_PIO;
0788
0789 info->host = host;
0790
0791 if (scsi_add_host(host, NULL))
0792 goto err_free_irq;
0793
0794 scsi_scan_host(host);
0795
0796 return 0;
0797
0798 err_free_irq:
0799 free_irq(irq_level, host);
0800 err_free_scsi:
0801 scsi_host_put(host);
0802 err_release:
0803 release_region(port_base, 0x10);
0804 printk(KERN_INFO "sym53c500_cs: no SCSI devices found\n");
0805 return -ENODEV;
0806
0807 failed:
0808 SYM53C500_release(link);
0809 return -ENODEV;
0810 }
0811
0812 static int sym53c500_resume(struct pcmcia_device *link)
0813 {
0814 struct scsi_info_t *info = link->priv;
0815
0816
0817 if ((info->manf_id == MANFID_MACNICA) ||
0818 (info->manf_id == MANFID_PIONEER) ||
0819 (info->manf_id == 0x0098)) {
0820 outb(0x80, link->resource[0]->start + 0xd);
0821 outb(0x24, link->resource[0]->start + 0x9);
0822 outb(0x04, link->resource[0]->start + 0xd);
0823 }
0824
0825
0826
0827
0828 SYM53C500_int_host_reset(link->resource[0]->start);
0829
0830 return 0;
0831 }
0832
0833 static void
0834 SYM53C500_detach(struct pcmcia_device *link)
0835 {
0836 dev_dbg(&link->dev, "SYM53C500_detach\n");
0837
0838 SYM53C500_release(link);
0839
0840 kfree(link->priv);
0841 link->priv = NULL;
0842 }
0843
0844 static int
0845 SYM53C500_probe(struct pcmcia_device *link)
0846 {
0847 struct scsi_info_t *info;
0848
0849 dev_dbg(&link->dev, "SYM53C500_attach()\n");
0850
0851
0852 info = kzalloc(sizeof(*info), GFP_KERNEL);
0853 if (!info)
0854 return -ENOMEM;
0855 info->p_dev = link;
0856 link->priv = info;
0857 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
0858
0859 return SYM53C500_config(link);
0860 }
0861
0862 MODULE_AUTHOR("Bob Tracy <rct@frus.com>");
0863 MODULE_DESCRIPTION("SYM53C500 PCMCIA SCSI driver");
0864 MODULE_LICENSE("GPL");
0865
0866 static const struct pcmcia_device_id sym53c500_ids[] = {
0867 PCMCIA_DEVICE_PROD_ID12("BASICS by New Media Corporation", "SCSI Sym53C500", 0x23c78a9d, 0x0099e7f7),
0868 PCMCIA_DEVICE_PROD_ID12("New Media Corporation", "SCSI Bus Toaster Sym53C500", 0x085a850b, 0x45432eb8),
0869 PCMCIA_DEVICE_PROD_ID2("SCSI9000", 0x21648f44),
0870 PCMCIA_DEVICE_NULL,
0871 };
0872 MODULE_DEVICE_TABLE(pcmcia, sym53c500_ids);
0873
0874 static struct pcmcia_driver sym53c500_cs_driver = {
0875 .owner = THIS_MODULE,
0876 .name = "sym53c500_cs",
0877 .probe = SYM53C500_probe,
0878 .remove = SYM53C500_detach,
0879 .id_table = sym53c500_ids,
0880 .resume = sym53c500_resume,
0881 };
0882 module_pcmcia_driver(sym53c500_cs_driver);