• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/drivers/scsi/pcmcia/
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.h>
53#include <pcmcia/cistpl.h>
54#include <pcmcia/ds.h>
55
56
57/*====================================================================*/
58
59/* Parameters that can be set with 'insmod' */
60
61/* SCSI bus setup options */
62static int host_id = 7;
63static int reconnect = 1;
64static int parity = 1;
65static int synchronous = 1;
66static int reset_delay = 100;
67static int ext_trans = 0;
68
69module_param(host_id, int, 0);
70module_param(reconnect, int, 0);
71module_param(parity, int, 0);
72module_param(synchronous, int, 0);
73module_param(reset_delay, int, 0);
74module_param(ext_trans, int, 0);
75
76MODULE_LICENSE("Dual MPL/GPL");
77
78/*====================================================================*/
79
80typedef struct scsi_info_t {
81	struct pcmcia_device	*p_dev;
82    struct Scsi_Host	*host;
83} scsi_info_t;
84
85static void aha152x_release_cs(struct pcmcia_device *link);
86static void aha152x_detach(struct pcmcia_device *p_dev);
87static int aha152x_config_cs(struct pcmcia_device *link);
88
89static struct pcmcia_device *dev_list;
90
91static int aha152x_probe(struct pcmcia_device *link)
92{
93    scsi_info_t *info;
94
95    dev_dbg(&link->dev, "aha152x_attach()\n");
96
97    /* Create new SCSI device */
98    info = kzalloc(sizeof(*info), GFP_KERNEL);
99    if (!info) return -ENOMEM;
100    info->p_dev = link;
101    link->priv = info;
102
103    link->resource[0]->end = 0x20;
104    link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
105    link->conf.Attributes = CONF_ENABLE_IRQ;
106    link->conf.IntType = INT_MEMORY_AND_IO;
107    link->conf.Present = PRESENT_OPTION;
108
109    return aha152x_config_cs(link);
110} /* aha152x_attach */
111
112/*====================================================================*/
113
114static void aha152x_detach(struct pcmcia_device *link)
115{
116    dev_dbg(&link->dev, "aha152x_detach\n");
117
118    aha152x_release_cs(link);
119
120    /* Unlink device structure, free bits */
121    kfree(link->priv);
122} /* aha152x_detach */
123
124/*====================================================================*/
125
126static int aha152x_config_check(struct pcmcia_device *p_dev,
127				cistpl_cftable_entry_t *cfg,
128				cistpl_cftable_entry_t *dflt,
129				unsigned int vcc,
130				void *priv_data)
131{
132	p_dev->io_lines = 10;
133	/* For New Media T&J, look for a SCSI window */
134	if (cfg->io.win[0].len >= 0x20)
135		p_dev->resource[0]->start = cfg->io.win[0].base;
136	else if ((cfg->io.nwin > 1) &&
137		 (cfg->io.win[1].len >= 0x20))
138		p_dev->resource[0]->start = cfg->io.win[1].base;
139	if ((cfg->io.nwin > 0) &&
140	    (p_dev->resource[0]->start < 0xffff)) {
141		if (!pcmcia_request_io(p_dev))
142			return 0;
143	}
144	return -EINVAL;
145}
146
147static int aha152x_config_cs(struct pcmcia_device *link)
148{
149    scsi_info_t *info = link->priv;
150    struct aha152x_setup s;
151    int ret;
152    struct Scsi_Host *host;
153
154    dev_dbg(&link->dev, "aha152x_config\n");
155
156    ret = pcmcia_loop_config(link, aha152x_config_check, NULL);
157    if (ret)
158	    goto failed;
159
160    if (!link->irq)
161	    goto failed;
162
163    ret = pcmcia_request_configuration(link, &link->conf);
164    if (ret)
165	    goto failed;
166
167    /* Set configuration options for the aha152x driver */
168    memset(&s, 0, sizeof(s));
169    s.conf        = "PCMCIA setup";
170    s.io_port     = link->resource[0]->start;
171    s.irq         = link->irq;
172    s.scsiid      = host_id;
173    s.reconnect   = reconnect;
174    s.parity      = parity;
175    s.synchronous = synchronous;
176    s.delay       = reset_delay;
177    if (ext_trans)
178        s.ext_trans = ext_trans;
179
180    host = aha152x_probe_one(&s);
181    if (host == NULL) {
182	printk(KERN_INFO "aha152x_cs: no SCSI devices found\n");
183	goto failed;
184    }
185
186    info->host = host;
187
188    return 0;
189
190failed:
191    aha152x_release_cs(link);
192    return -ENODEV;
193}
194
195static void aha152x_release_cs(struct pcmcia_device *link)
196{
197	scsi_info_t *info = link->priv;
198
199	aha152x_release(info->host);
200	pcmcia_disable_device(link);
201}
202
203static int aha152x_resume(struct pcmcia_device *link)
204{
205	scsi_info_t *info = link->priv;
206
207	aha152x_host_reset_host(info->host);
208
209	return 0;
210}
211
212static struct pcmcia_device_id aha152x_ids[] = {
213	PCMCIA_DEVICE_PROD_ID123("New Media", "SCSI", "Bus Toaster", 0xcdf7e4cc, 0x35f26476, 0xa8851d6e),
214	PCMCIA_DEVICE_PROD_ID123("NOTEWORTHY", "SCSI", "Bus Toaster", 0xad89c6e8, 0x35f26476, 0xa8851d6e),
215	PCMCIA_DEVICE_PROD_ID12("Adaptec, Inc.", "APA-1460 SCSI Host Adapter", 0x24ba9738, 0x3a3c3d20),
216	PCMCIA_DEVICE_PROD_ID12("New Media Corporation", "Multimedia Sound/SCSI", 0x085a850b, 0x80a6535c),
217	PCMCIA_DEVICE_PROD_ID12("NOTEWORTHY", "NWCOMB02 SCSI/AUDIO COMBO CARD", 0xad89c6e8, 0x5f9a615b),
218	PCMCIA_DEVICE_NULL,
219};
220MODULE_DEVICE_TABLE(pcmcia, aha152x_ids);
221
222static struct pcmcia_driver aha152x_cs_driver = {
223	.owner		= THIS_MODULE,
224	.drv		= {
225		.name	= "aha152x_cs",
226	},
227	.probe		= aha152x_probe,
228	.remove		= aha152x_detach,
229	.id_table       = aha152x_ids,
230	.resume		= aha152x_resume,
231};
232
233static int __init init_aha152x_cs(void)
234{
235	return pcmcia_register_driver(&aha152x_cs_driver);
236}
237
238static void __exit exit_aha152x_cs(void)
239{
240	pcmcia_unregister_driver(&aha152x_cs_driver);
241	BUG_ON(dev_list != NULL);
242}
243
244module_init(init_aha152x_cs);
245module_exit(exit_aha152x_cs);
246