Back to home page

OSCL-LXR

 
 

    


0001 /*======================================================================
0002 
0003     A driver for Adaptec AHA152X-compatible PCMCIA SCSI cards.
0004 
0005     This driver supports the Adaptec AHA-1460, the New Media Bus
0006     Toaster, and the New Media Toast & Jam.
0007     
0008     aha152x_cs.c 1.54 2000/06/12 21:27:25
0009 
0010     The contents of this file are subject to the Mozilla Public
0011     License Version 1.1 (the "License"); you may not use this file
0012     except in compliance with the License. You may obtain a copy of
0013     the License at http://www.mozilla.org/MPL/
0014 
0015     Software distributed under the License is distributed on an "AS
0016     IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
0017     implied. See the License for the specific language governing
0018     rights and limitations under the License.
0019 
0020     The initial developer of the original code is David A. Hinds
0021     <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
0022     are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
0023 
0024     Alternatively, the contents of this file may be used under the
0025     terms of the GNU General Public License version 2 (the "GPL"), in which
0026     case the provisions of the GPL are applicable instead of the
0027     above.  If you wish to allow the use of your version of this file
0028     only under the terms of the GPL and not to allow others to use
0029     your version of this file under the MPL, indicate your decision
0030     by deleting the provisions above and replace them with the notice
0031     and other provisions required by the GPL.  If you do not delete
0032     the provisions above, a recipient may use your version of this
0033     file under either the MPL or the GPL.
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 /* Parameters that can be set with 'insmod' */
0062 
0063 /* SCSI bus setup options */
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     /* Create new SCSI device */
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 } /* aha152x_attach */
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     /* Unlink device structure, free bits */
0118     kfree(link->priv);
0119 } /* aha152x_detach */
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     /* For New Media T&J, look for a SCSI window */
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     /* Set configuration options for the aha152x driver */
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);