[PATCH] pcmcia: remove dev_link_t and client_handle_t indirection
[linux-2.6-block.git] / drivers / scsi / pcmcia / fdomain_stub.c
CommitLineData
1da177e4
LT
1/*======================================================================
2
3 A driver for Future Domain-compatible PCMCIA SCSI cards
4
5 fdomain_cs.c 1.47 2001/10/13 00:08:52
6
7 The contents of this file are subject to the Mozilla Public
8 License Version 1.1 (the "License"); you may not use this file
9 except in compliance with the License. You may obtain a copy of
10 the License at http://www.mozilla.org/MPL/
11
12 Software distributed under the License is distributed on an "AS
13 IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
14 implied. See the License for the specific language governing
15 rights and limitations under the License.
16
17 The initial developer of the original code is David A. Hinds
18 <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
19 are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
20
21 Alternatively, the contents of this file may be used under the
22 terms of the GNU General Public License version 2 (the "GPL"), in
23 which case the provisions of the GPL are applicable instead of the
24 above. If you wish to allow the use of your version of this file
25 only under the terms of the GPL and not to allow others to use
26 your version of this file under the MPL, indicate your decision
27 by deleting the provisions above and replace them with the notice
28 and other provisions required by the GPL. If you do not delete
29 the provisions above, a recipient may use your version of this
30 file under either the MPL or the GPL.
31
32======================================================================*/
33
34#include <linux/module.h>
35#include <linux/init.h>
36#include <linux/kernel.h>
37#include <linux/sched.h>
38#include <linux/slab.h>
39#include <linux/string.h>
40#include <linux/ioport.h>
41#include <scsi/scsi.h>
42#include <linux/major.h>
43#include <linux/blkdev.h>
44#include <scsi/scsi_ioctl.h>
45
46#include "scsi.h"
47#include <scsi/scsi_host.h>
48#include "fdomain.h"
49
1da177e4
LT
50#include <pcmcia/cs_types.h>
51#include <pcmcia/cs.h>
52#include <pcmcia/cistpl.h>
53#include <pcmcia/ds.h>
54
55/*====================================================================*/
56
57/* Module parameters */
58
59MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
60MODULE_DESCRIPTION("Future Domain PCMCIA SCSI driver");
61MODULE_LICENSE("Dual MPL/GPL");
62
63#ifdef PCMCIA_DEBUG
64static int pc_debug = PCMCIA_DEBUG;
65module_param(pc_debug, int, 0);
66#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
67static char *version =
68"fdomain_cs.c 1.47 2001/10/13 00:08:52 (David Hinds)";
69#else
70#define DEBUG(n, args...)
71#endif
72
73/*====================================================================*/
74
75typedef struct scsi_info_t {
fd238232 76 struct pcmcia_device *p_dev;
1da177e4
LT
77 dev_node_t node;
78 struct Scsi_Host *host;
79} scsi_info_t;
80
81
fba395ee 82static void fdomain_release(struct pcmcia_device *link);
cc3b4866 83static void fdomain_detach(struct pcmcia_device *p_dev);
fba395ee 84static void fdomain_config(struct pcmcia_device *link);
1da177e4 85
fba395ee 86static int fdomain_attach(struct pcmcia_device *link)
1da177e4
LT
87{
88 scsi_info_t *info;
f8cfa618 89
1da177e4
LT
90 DEBUG(0, "fdomain_attach()\n");
91
92 /* Create new SCSI device */
93 info = kmalloc(sizeof(*info), GFP_KERNEL);
f8cfa618 94 if (!info) return -ENOMEM;
1da177e4 95 memset(info, 0, sizeof(*info));
fba395ee 96 info->p_dev = link;
fd238232 97 link->priv = info;
1da177e4
LT
98 link->io.NumPorts1 = 0x10;
99 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
100 link->io.IOAddrLines = 10;
101 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
102 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
103 link->conf.Attributes = CONF_ENABLE_IRQ;
1da177e4
LT
104 link->conf.IntType = INT_MEMORY_AND_IO;
105 link->conf.Present = PRESENT_OPTION;
106
f8cfa618
DB
107 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
108 fdomain_config(link);
109
110 return 0;
1da177e4
LT
111} /* fdomain_attach */
112
113/*====================================================================*/
114
fba395ee 115static void fdomain_detach(struct pcmcia_device *link)
1da177e4 116{
b4635811
DB
117 DEBUG(0, "fdomain_detach(0x%p)\n", link);
118
119 if (link->state & DEV_CONFIG)
120 fdomain_release(link);
121
122 kfree(link->priv);
1da177e4
LT
123} /* fdomain_detach */
124
125/*====================================================================*/
126
127#define CS_CHECK(fn, ret) \
128do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
129
fba395ee 130static void fdomain_config(struct pcmcia_device *link)
1da177e4 131{
1da177e4
LT
132 scsi_info_t *info = link->priv;
133 tuple_t tuple;
134 cisparse_t parse;
135 int i, last_ret, last_fn;
136 u_char tuple_data[64];
137 char str[16];
138 struct Scsi_Host *host;
139
140 DEBUG(0, "fdomain_config(0x%p)\n", link);
141
142 tuple.DesiredTuple = CISTPL_CONFIG;
143 tuple.TupleData = tuple_data;
144 tuple.TupleDataMax = 64;
145 tuple.TupleOffset = 0;
fba395ee
DB
146 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
147 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
148 CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
1da177e4
LT
149 link->conf.ConfigBase = parse.config.base;
150
151 /* Configure card */
152 link->state |= DEV_CONFIG;
153
154 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
fba395ee 155 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
1da177e4 156 while (1) {
fba395ee
DB
157 if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
158 pcmcia_parse_tuple(link, &tuple, &parse) != 0)
1da177e4
LT
159 goto next_entry;
160 link->conf.ConfigIndex = parse.cftable_entry.index;
161 link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
fba395ee 162 i = pcmcia_request_io(link, &link->io);
1da177e4
LT
163 if (i == CS_SUCCESS) break;
164 next_entry:
fba395ee 165 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
1da177e4
LT
166 }
167
fba395ee
DB
168 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
169 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
1da177e4
LT
170
171 /* A bad hack... */
172 release_region(link->io.BasePort1, link->io.NumPorts1);
173
174 /* Set configuration options for the fdomain driver */
175 sprintf(str, "%d,%d", link->io.BasePort1, link->irq.AssignedIRQ);
176 fdomain_setup(str);
177
178 host = __fdomain_16x0_detect(&fdomain_driver_template);
179 if (!host) {
180 printk(KERN_INFO "fdomain_cs: no SCSI devices found\n");
181 goto cs_failed;
182 }
183
184 scsi_add_host(host, NULL); /* XXX handle failure */
185 scsi_scan_host(host);
186
187 sprintf(info->node.dev_name, "scsi%d", host->host_no);
fd238232 188 link->dev_node = &info->node;
1da177e4
LT
189 info->host = host;
190
191 link->state &= ~DEV_CONFIG_PENDING;
192 return;
193
194cs_failed:
fba395ee 195 cs_error(link, last_fn, last_ret);
1da177e4
LT
196 fdomain_release(link);
197 return;
198
199} /* fdomain_config */
200
201/*====================================================================*/
202
fba395ee 203static void fdomain_release(struct pcmcia_device *link)
1da177e4 204{
5f2a71fc 205 scsi_info_t *info = link->priv;
1da177e4 206
5f2a71fc 207 DEBUG(0, "fdomain_release(0x%p)\n", link);
1da177e4 208
5f2a71fc 209 scsi_remove_host(info->host);
fba395ee 210 pcmcia_disable_device(link);
5f2a71fc 211 scsi_unregister(info->host);
1da177e4
LT
212}
213
214/*====================================================================*/
215
fba395ee 216static int fdomain_resume(struct pcmcia_device *link)
98e4c28b 217{
8661bb5b 218 if (link->state & DEV_CONFIG)
98e4c28b 219 fdomain_16x0_bus_reset(NULL);
98e4c28b
DB
220
221 return 0;
222}
223
2d1fb376
DB
224static struct pcmcia_device_id fdomain_ids[] = {
225 PCMCIA_DEVICE_PROD_ID12("IBM Corp.", "SCSI PCMCIA Card", 0xe3736c88, 0x859cad20),
226 PCMCIA_DEVICE_PROD_ID1("SCSI PCMCIA Adapter Card", 0x8dacb57e),
227 PCMCIA_DEVICE_PROD_ID12(" SIMPLE TECHNOLOGY Corporation", "SCSI PCMCIA Credit Card Controller", 0x182bdafe, 0xc80d106f),
228 PCMCIA_DEVICE_NULL,
229};
230MODULE_DEVICE_TABLE(pcmcia, fdomain_ids);
231
1da177e4
LT
232static struct pcmcia_driver fdomain_cs_driver = {
233 .owner = THIS_MODULE,
234 .drv = {
235 .name = "fdomain_cs",
236 },
f8cfa618 237 .probe = fdomain_attach,
cc3b4866 238 .remove = fdomain_detach,
2d1fb376 239 .id_table = fdomain_ids,
98e4c28b 240 .resume = fdomain_resume,
1da177e4
LT
241};
242
243static int __init init_fdomain_cs(void)
244{
245 return pcmcia_register_driver(&fdomain_cs_driver);
246}
247
248static void __exit exit_fdomain_cs(void)
249{
250 pcmcia_unregister_driver(&fdomain_cs_driver);
1da177e4
LT
251}
252
253module_init(init_fdomain_cs);
254module_exit(exit_fdomain_cs);