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
0032
0033
0034
0035
0036
0037 #include <linux/module.h>
0038 #include <linux/init.h>
0039 #include <linux/kernel.h>
0040 #include <linux/slab.h>
0041 #include <linux/string.h>
0042 #include <linux/ioport.h>
0043 #include <linux/major.h>
0044 #include <linux/blkdev.h>
0045
0046 #include <scsi/scsi.h>
0047 #include <scsi/scsi_cmnd.h>
0048 #include <scsi/scsi_device.h>
0049 #include <scsi/scsi_eh.h>
0050 #include <scsi/scsi_host.h>
0051 #include <scsi/scsi_ioctl.h>
0052 #include <scsi/scsi_tcq.h>
0053 #include "aha152x.h"
0054
0055 #include <pcmcia/cistpl.h>
0056 #include <pcmcia/ds.h>
0057
0058
0059
0060
0061
0062
0063
0064 static int host_id = 7;
0065 static int reconnect = 1;
0066 static int parity = 1;
0067 static int synchronous = 1;
0068 static int reset_delay = 100;
0069 static int ext_trans = 0;
0070
0071 module_param(host_id, int, 0);
0072 module_param(reconnect, int, 0);
0073 module_param(parity, int, 0);
0074 module_param(synchronous, int, 0);
0075 module_param(reset_delay, int, 0);
0076 module_param(ext_trans, int, 0);
0077
0078 MODULE_LICENSE("Dual MPL/GPL");
0079
0080
0081
0082 typedef struct scsi_info_t {
0083 struct pcmcia_device *p_dev;
0084 struct Scsi_Host *host;
0085 } scsi_info_t;
0086
0087 static void aha152x_release_cs(struct pcmcia_device *link);
0088 static void aha152x_detach(struct pcmcia_device *p_dev);
0089 static int aha152x_config_cs(struct pcmcia_device *link);
0090
0091 static int aha152x_probe(struct pcmcia_device *link)
0092 {
0093 scsi_info_t *info;
0094
0095 dev_dbg(&link->dev, "aha152x_attach()\n");
0096
0097
0098 info = kzalloc(sizeof(*info), GFP_KERNEL);
0099 if (!info) return -ENOMEM;
0100 info->p_dev = link;
0101 link->priv = info;
0102
0103 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
0104 link->config_regs = PRESENT_OPTION;
0105
0106 return aha152x_config_cs(link);
0107 }
0108
0109
0110
0111 static void aha152x_detach(struct pcmcia_device *link)
0112 {
0113 dev_dbg(&link->dev, "aha152x_detach\n");
0114
0115 aha152x_release_cs(link);
0116
0117
0118 kfree(link->priv);
0119 }
0120
0121
0122
0123 static int aha152x_config_check(struct pcmcia_device *p_dev, void *priv_data)
0124 {
0125 p_dev->io_lines = 10;
0126
0127
0128 if ((p_dev->resource[0]->end < 0x20) &&
0129 (p_dev->resource[1]->end >= 0x20))
0130 p_dev->resource[0]->start = p_dev->resource[1]->start;
0131
0132 if (p_dev->resource[0]->start >= 0xffff)
0133 return -EINVAL;
0134
0135 p_dev->resource[1]->start = p_dev->resource[1]->end = 0;
0136 p_dev->resource[0]->end = 0x20;
0137 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
0138 p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
0139
0140 return pcmcia_request_io(p_dev);
0141 }
0142
0143 static int aha152x_config_cs(struct pcmcia_device *link)
0144 {
0145 scsi_info_t *info = link->priv;
0146 struct aha152x_setup s;
0147 int ret;
0148 struct Scsi_Host *host;
0149
0150 dev_dbg(&link->dev, "aha152x_config\n");
0151
0152 ret = pcmcia_loop_config(link, aha152x_config_check, NULL);
0153 if (ret)
0154 goto failed;
0155
0156 if (!link->irq)
0157 goto failed;
0158
0159 ret = pcmcia_enable_device(link);
0160 if (ret)
0161 goto failed;
0162
0163
0164 memset(&s, 0, sizeof(s));
0165 s.conf = "PCMCIA setup";
0166 s.io_port = link->resource[0]->start;
0167 s.irq = link->irq;
0168 s.scsiid = host_id;
0169 s.reconnect = reconnect;
0170 s.parity = parity;
0171 s.synchronous = synchronous;
0172 s.delay = reset_delay;
0173 if (ext_trans)
0174 s.ext_trans = ext_trans;
0175
0176 host = aha152x_probe_one(&s);
0177 if (host == NULL) {
0178 printk(KERN_INFO "aha152x_cs: no SCSI devices found\n");
0179 goto failed;
0180 }
0181
0182 info->host = host;
0183
0184 return 0;
0185
0186 failed:
0187 aha152x_release_cs(link);
0188 return -ENODEV;
0189 }
0190
0191 static void aha152x_release_cs(struct pcmcia_device *link)
0192 {
0193 scsi_info_t *info = link->priv;
0194
0195 aha152x_release(info->host);
0196 pcmcia_disable_device(link);
0197 }
0198
0199 static int aha152x_resume(struct pcmcia_device *link)
0200 {
0201 scsi_info_t *info = link->priv;
0202
0203 aha152x_host_reset_host(info->host);
0204
0205 return 0;
0206 }
0207
0208 static const struct pcmcia_device_id aha152x_ids[] = {
0209 PCMCIA_DEVICE_PROD_ID123("New Media", "SCSI", "Bus Toaster", 0xcdf7e4cc, 0x35f26476, 0xa8851d6e),
0210 PCMCIA_DEVICE_PROD_ID123("NOTEWORTHY", "SCSI", "Bus Toaster", 0xad89c6e8, 0x35f26476, 0xa8851d6e),
0211 PCMCIA_DEVICE_PROD_ID12("Adaptec, Inc.", "APA-1460 SCSI Host Adapter", 0x24ba9738, 0x3a3c3d20),
0212 PCMCIA_DEVICE_PROD_ID12("New Media Corporation", "Multimedia Sound/SCSI", 0x085a850b, 0x80a6535c),
0213 PCMCIA_DEVICE_PROD_ID12("NOTEWORTHY", "NWCOMB02 SCSI/AUDIO COMBO CARD", 0xad89c6e8, 0x5f9a615b),
0214 PCMCIA_DEVICE_NULL,
0215 };
0216 MODULE_DEVICE_TABLE(pcmcia, aha152x_ids);
0217
0218 static struct pcmcia_driver aha152x_cs_driver = {
0219 .owner = THIS_MODULE,
0220 .name = "aha152x_cs",
0221 .probe = aha152x_probe,
0222 .remove = aha152x_detach,
0223 .id_table = aha152x_ids,
0224 .resume = aha152x_resume,
0225 };
0226 module_pcmcia_driver(aha152x_cs_driver);