linux/drivers/scsi/pcmcia/aha152x_stub.c
<<
>>
Prefs
   1/*======================================================================
   2
   3    A driver for Adaptec AHA152X-compatible PCMCIA SCSI cards.
   4
   5    This driver supports the Adaptec AHA-1460, the New Media Bus
   6    Toaster, and the New Media Toast & Jam.
   7    
   8    aha152x_cs.c 1.54 2000/06/12 21:27:25
   9
  10    The contents of this file are subject to the Mozilla Public
  11    License Version 1.1 (the "License"); you may not use this file
  12    except in compliance with the License. You may obtain a copy of
  13    the License at http://www.mozilla.org/MPL/
  14
  15    Software distributed under the License is distributed on an "AS
  16    IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  17    implied. See the License for the specific language governing
  18    rights and limitations under the License.
  19
  20    The initial developer of the original code is David A. Hinds
  21    <dahinds@users.sourceforge.net>.  Portions created by David A. Hinds
  22    are Copyright (C) 1999 David A. Hinds.  All Rights Reserved.
  23
  24    Alternatively, the contents of this file may be used under the
  25    terms of the GNU General Public License version 2 (the "GPL"), in which
  26    case the provisions of the GPL are applicable instead of the
  27    above.  If you wish to allow the use of your version of this file
  28    only under the terms of the GPL and not to allow others to use
  29    your version of this file under the MPL, indicate your decision
  30    by deleting the provisions above and replace them with the notice
  31    and other provisions required by the GPL.  If you do not delete
  32    the provisions above, a recipient may use your version of this
  33    file under either the MPL or the GPL.
  34    
  35======================================================================*/
  36
  37#include <linux/module.h>
  38#include <linux/init.h>
  39#include <linux/kernel.h>
  40#include <linux/slab.h>
  41#include <linux/string.h>
  42#include <linux/ioport.h>
  43#include <scsi/scsi.h>
  44#include <linux/major.h>
  45#include <linux/blkdev.h>
  46#include <scsi/scsi_ioctl.h>
  47
  48#include "scsi.h"
  49#include <scsi/scsi_host.h>
  50#include "aha152x.h"
  51
  52#include <pcmcia/cs_types.h>
  53#include <pcmcia/cs.h>
  54#include <pcmcia/cistpl.h>
  55#include <pcmcia/ds.h>
  56
  57#ifdef PCMCIA_DEBUG
  58static int pc_debug = PCMCIA_DEBUG;
  59module_param(pc_debug, int, 0644);
  60#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
  61static char *version =
  62"aha152x_cs.c 1.54 2000/06/12 21:27:25 (David Hinds)";
  63#else
  64#define DEBUG(n, args...)
  65#endif
  66
  67/*====================================================================*/
  68
  69/* Parameters that can be set with 'insmod' */
  70
  71/* SCSI bus setup options */
  72static int host_id = 7;
  73static int reconnect = 1;
  74static int parity = 1;
  75static int synchronous = 1;
  76static int reset_delay = 100;
  77static int ext_trans = 0;
  78
  79module_param(host_id, int, 0);
  80module_param(reconnect, int, 0);
  81module_param(parity, int, 0);
  82module_param(synchronous, int, 0);
  83module_param(reset_delay, int, 0);
  84module_param(ext_trans, int, 0);
  85
  86MODULE_LICENSE("Dual MPL/GPL");
  87
  88/*====================================================================*/
  89
  90typedef struct scsi_info_t {
  91        struct pcmcia_device    *p_dev;
  92    dev_node_t          node;
  93    struct Scsi_Host    *host;
  94} scsi_info_t;
  95
  96static void aha152x_release_cs(struct pcmcia_device *link);
  97static void aha152x_detach(struct pcmcia_device *p_dev);
  98static int aha152x_config_cs(struct pcmcia_device *link);
  99
 100static struct pcmcia_device *dev_list;
 101
 102static int aha152x_probe(struct pcmcia_device *link)
 103{
 104    scsi_info_t *info;
 105
 106    DEBUG(0, "aha152x_attach()\n");
 107
 108    /* Create new SCSI device */
 109    info = kzalloc(sizeof(*info), GFP_KERNEL);
 110    if (!info) return -ENOMEM;
 111    info->p_dev = link;
 112    link->priv = info;
 113
 114    link->io.NumPorts1 = 0x20;
 115    link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
 116    link->io.IOAddrLines = 10;
 117    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
 118    link->irq.IRQInfo1 = IRQ_LEVEL_ID;
 119    link->conf.Attributes = CONF_ENABLE_IRQ;
 120    link->conf.IntType = INT_MEMORY_AND_IO;
 121    link->conf.Present = PRESENT_OPTION;
 122
 123    return aha152x_config_cs(link);
 124} /* aha152x_attach */
 125
 126/*====================================================================*/
 127
 128static void aha152x_detach(struct pcmcia_device *link)
 129{
 130    DEBUG(0, "aha152x_detach(0x%p)\n", link);
 131
 132    aha152x_release_cs(link);
 133
 134    /* Unlink device structure, free bits */
 135    kfree(link->priv);
 136} /* aha152x_detach */
 137
 138/*====================================================================*/
 139
 140#define CS_CHECK(fn, ret) \
 141do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
 142
 143static int aha152x_config_check(struct pcmcia_device *p_dev,
 144                                cistpl_cftable_entry_t *cfg,
 145                                cistpl_cftable_entry_t *dflt,
 146                                unsigned int vcc,
 147                                void *priv_data)
 148{
 149        /* For New Media T&J, look for a SCSI window */
 150        if (cfg->io.win[0].len >= 0x20)
 151                p_dev->io.BasePort1 = cfg->io.win[0].base;
 152        else if ((cfg->io.nwin > 1) &&
 153                 (cfg->io.win[1].len >= 0x20))
 154                p_dev->io.BasePort1 = cfg->io.win[1].base;
 155        if ((cfg->io.nwin > 0) &&
 156            (p_dev->io.BasePort1 < 0xffff)) {
 157                if (!pcmcia_request_io(p_dev, &p_dev->io))
 158                        return 0;
 159        }
 160        return -EINVAL;
 161}
 162
 163static int aha152x_config_cs(struct pcmcia_device *link)
 164{
 165    scsi_info_t *info = link->priv;
 166    struct aha152x_setup s;
 167    int last_ret, last_fn;
 168    struct Scsi_Host *host;
 169
 170    DEBUG(0, "aha152x_config(0x%p)\n", link);
 171
 172    last_ret = pcmcia_loop_config(link, aha152x_config_check, NULL);
 173    if (last_ret) {
 174        cs_error(link, RequestIO, last_ret);
 175        goto failed;
 176    }
 177
 178    CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
 179    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
 180    
 181    /* Set configuration options for the aha152x driver */
 182    memset(&s, 0, sizeof(s));
 183    s.conf        = "PCMCIA setup";
 184    s.io_port     = link->io.BasePort1;
 185    s.irq         = link->irq.AssignedIRQ;
 186    s.scsiid      = host_id;
 187    s.reconnect   = reconnect;
 188    s.parity      = parity;
 189    s.synchronous = synchronous;
 190    s.delay       = reset_delay;
 191    if (ext_trans)
 192        s.ext_trans = ext_trans;
 193
 194    host = aha152x_probe_one(&s);
 195    if (host == NULL) {
 196        printk(KERN_INFO "aha152x_cs: no SCSI devices found\n");
 197        goto cs_failed;
 198    }
 199
 200    sprintf(info->node.dev_name, "scsi%d", host->host_no);
 201    link->dev_node = &info->node;
 202    info->host = host;
 203
 204    return 0;
 205
 206cs_failed:
 207    cs_error(link, last_fn, last_ret);
 208failed:
 209    aha152x_release_cs(link);
 210    return -ENODEV;
 211}
 212
 213static void aha152x_release_cs(struct pcmcia_device *link)
 214{
 215        scsi_info_t *info = link->priv;
 216
 217        aha152x_release(info->host);
 218        pcmcia_disable_device(link);
 219}
 220
 221static int aha152x_resume(struct pcmcia_device *link)
 222{
 223        scsi_info_t *info = link->priv;
 224
 225        aha152x_host_reset_host(info->host);
 226
 227        return 0;
 228}
 229
 230static struct pcmcia_device_id aha152x_ids[] = {
 231        PCMCIA_DEVICE_PROD_ID123("New Media", "SCSI", "Bus Toaster", 0xcdf7e4cc, 0x35f26476, 0xa8851d6e),
 232        PCMCIA_DEVICE_PROD_ID123("NOTEWORTHY", "SCSI", "Bus Toaster", 0xad89c6e8, 0x35f26476, 0xa8851d6e),
 233        PCMCIA_DEVICE_PROD_ID12("Adaptec, Inc.", "APA-1460 SCSI Host Adapter", 0x24ba9738, 0x3a3c3d20),
 234        PCMCIA_DEVICE_PROD_ID12("New Media Corporation", "Multimedia Sound/SCSI", 0x085a850b, 0x80a6535c),
 235        PCMCIA_DEVICE_PROD_ID12("NOTEWORTHY", "NWCOMB02 SCSI/AUDIO COMBO CARD", 0xad89c6e8, 0x5f9a615b),
 236        PCMCIA_DEVICE_NULL,
 237};
 238MODULE_DEVICE_TABLE(pcmcia, aha152x_ids);
 239
 240static struct pcmcia_driver aha152x_cs_driver = {
 241        .owner          = THIS_MODULE,
 242        .drv            = {
 243                .name   = "aha152x_cs",
 244        },
 245        .probe          = aha152x_probe,
 246        .remove         = aha152x_detach,
 247        .id_table       = aha152x_ids,
 248        .resume         = aha152x_resume,
 249};
 250
 251static int __init init_aha152x_cs(void)
 252{
 253        return pcmcia_register_driver(&aha152x_cs_driver);
 254}
 255
 256static void __exit exit_aha152x_cs(void)
 257{
 258        pcmcia_unregister_driver(&aha152x_cs_driver);
 259        BUG_ON(dev_list != NULL);
 260}
 261
 262module_init(init_aha152x_cs);
 263module_exit(exit_aha152x_cs);
 264