aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/pcmcia/fdomain_stub.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/pcmcia/fdomain_stub.c')
-rw-r--r--drivers/scsi/pcmcia/fdomain_stub.c117
1 files changed, 37 insertions, 80 deletions
diff --git a/drivers/scsi/pcmcia/fdomain_stub.c b/drivers/scsi/pcmcia/fdomain_stub.c
index db8f5cd85ffe..788c58d805f3 100644
--- a/drivers/scsi/pcmcia/fdomain_stub.c
+++ b/drivers/scsi/pcmcia/fdomain_stub.c
@@ -80,29 +80,19 @@ typedef struct scsi_info_t {
80 80
81 81
82static void fdomain_release(dev_link_t *link); 82static void fdomain_release(dev_link_t *link);
83static int fdomain_event(event_t event, int priority, 83static void fdomain_detach(struct pcmcia_device *p_dev);
84 event_callback_args_t *args); 84static void fdomain_config(dev_link_t *link);
85 85
86static dev_link_t *fdomain_attach(void); 86static int fdomain_attach(struct pcmcia_device *p_dev)
87static void fdomain_detach(dev_link_t *);
88
89
90static dev_link_t *dev_list = NULL;
91
92static dev_info_t dev_info = "fdomain_cs";
93
94static dev_link_t *fdomain_attach(void)
95{ 87{
96 scsi_info_t *info; 88 scsi_info_t *info;
97 client_reg_t client_reg;
98 dev_link_t *link; 89 dev_link_t *link;
99 int ret; 90
100
101 DEBUG(0, "fdomain_attach()\n"); 91 DEBUG(0, "fdomain_attach()\n");
102 92
103 /* Create new SCSI device */ 93 /* Create new SCSI device */
104 info = kmalloc(sizeof(*info), GFP_KERNEL); 94 info = kmalloc(sizeof(*info), GFP_KERNEL);
105 if (!info) return NULL; 95 if (!info) return -ENOMEM;
106 memset(info, 0, sizeof(*info)); 96 memset(info, 0, sizeof(*info));
107 link = &info->link; link->priv = info; 97 link = &info->link; link->priv = info;
108 link->io.NumPorts1 = 0x10; 98 link->io.NumPorts1 = 0x10;
@@ -115,46 +105,27 @@ static dev_link_t *fdomain_attach(void)
115 link->conf.IntType = INT_MEMORY_AND_IO; 105 link->conf.IntType = INT_MEMORY_AND_IO;
116 link->conf.Present = PRESENT_OPTION; 106 link->conf.Present = PRESENT_OPTION;
117 107
118 /* Register with Card Services */ 108 link->handle = p_dev;
119 link->next = dev_list; 109 p_dev->instance = link;
120 dev_list = link; 110
121 client_reg.dev_info = &dev_info; 111 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
122 client_reg.Version = 0x0210; 112 fdomain_config(link);
123 client_reg.event_callback_args.client_data = link; 113
124 ret = pcmcia_register_client(&link->handle, &client_reg); 114 return 0;
125 if (ret != 0) {
126 cs_error(link->handle, RegisterClient, ret);
127 fdomain_detach(link);
128 return NULL;
129 }
130
131 return link;
132} /* fdomain_attach */ 115} /* fdomain_attach */
133 116
134/*====================================================================*/ 117/*====================================================================*/
135 118
136static void fdomain_detach(dev_link_t *link) 119static void fdomain_detach(struct pcmcia_device *p_dev)
137{ 120{
138 dev_link_t **linkp; 121 dev_link_t *link = dev_to_instance(p_dev);
139 122
140 DEBUG(0, "fdomain_detach(0x%p)\n", link); 123 DEBUG(0, "fdomain_detach(0x%p)\n", link);
141
142 /* Locate device structure */
143 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
144 if (*linkp == link) break;
145 if (*linkp == NULL)
146 return;
147 124
148 if (link->state & DEV_CONFIG) 125 if (link->state & DEV_CONFIG)
149 fdomain_release(link); 126 fdomain_release(link);
150 127
151 if (link->handle) 128 kfree(link->priv);
152 pcmcia_deregister_client(link->handle);
153
154 /* Unlink device structure, free bits */
155 *linkp = link->next;
156 kfree(link->priv);
157
158} /* fdomain_detach */ 129} /* fdomain_detach */
159 130
160/*====================================================================*/ 131/*====================================================================*/
@@ -256,43 +227,29 @@ static void fdomain_release(dev_link_t *link)
256 227
257/*====================================================================*/ 228/*====================================================================*/
258 229
259static int fdomain_event(event_t event, int priority, 230static int fdomain_suspend(struct pcmcia_device *dev)
260 event_callback_args_t *args)
261{ 231{
262 dev_link_t *link = args->client_data; 232 dev_link_t *link = dev_to_instance(dev);
263 233
264 DEBUG(1, "fdomain_event(0x%06x)\n", event);
265
266 switch (event) {
267 case CS_EVENT_CARD_REMOVAL:
268 link->state &= ~DEV_PRESENT;
269 if (link->state & DEV_CONFIG)
270 fdomain_release(link);
271 break;
272 case CS_EVENT_CARD_INSERTION:
273 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
274 fdomain_config(link);
275 break;
276 case CS_EVENT_PM_SUSPEND:
277 link->state |= DEV_SUSPEND; 234 link->state |= DEV_SUSPEND;
278 /* Fall through... */
279 case CS_EVENT_RESET_PHYSICAL:
280 if (link->state & DEV_CONFIG) 235 if (link->state & DEV_CONFIG)
281 pcmcia_release_configuration(link->handle); 236 pcmcia_release_configuration(link->handle);
282 break; 237
283 case CS_EVENT_PM_RESUME: 238 return 0;
239}
240
241static int fdomain_resume(struct pcmcia_device *dev)
242{
243 dev_link_t *link = dev_to_instance(dev);
244
284 link->state &= ~DEV_SUSPEND; 245 link->state &= ~DEV_SUSPEND;
285 /* Fall through... */
286 case CS_EVENT_CARD_RESET:
287 if (link->state & DEV_CONFIG) { 246 if (link->state & DEV_CONFIG) {
288 pcmcia_request_configuration(link->handle, &link->conf); 247 pcmcia_request_configuration(link->handle, &link->conf);
289 fdomain_16x0_bus_reset(NULL); 248 fdomain_16x0_bus_reset(NULL);
290 } 249 }
291 break;
292 }
293 return 0;
294} /* fdomain_event */
295 250
251 return 0;
252}
296 253
297static struct pcmcia_device_id fdomain_ids[] = { 254static struct pcmcia_device_id fdomain_ids[] = {
298 PCMCIA_DEVICE_PROD_ID12("IBM Corp.", "SCSI PCMCIA Card", 0xe3736c88, 0x859cad20), 255 PCMCIA_DEVICE_PROD_ID12("IBM Corp.", "SCSI PCMCIA Card", 0xe3736c88, 0x859cad20),
@@ -307,10 +264,11 @@ static struct pcmcia_driver fdomain_cs_driver = {
307 .drv = { 264 .drv = {
308 .name = "fdomain_cs", 265 .name = "fdomain_cs",
309 }, 266 },
310 .attach = fdomain_attach, 267 .probe = fdomain_attach,
311 .event = fdomain_event, 268 .remove = fdomain_detach,
312 .detach = fdomain_detach,
313 .id_table = fdomain_ids, 269 .id_table = fdomain_ids,
270 .suspend = fdomain_suspend,
271 .resume = fdomain_resume,
314}; 272};
315 273
316static int __init init_fdomain_cs(void) 274static int __init init_fdomain_cs(void)
@@ -321,7 +279,6 @@ static int __init init_fdomain_cs(void)
321static void __exit exit_fdomain_cs(void) 279static void __exit exit_fdomain_cs(void)
322{ 280{
323 pcmcia_unregister_driver(&fdomain_cs_driver); 281 pcmcia_unregister_driver(&fdomain_cs_driver);
324 BUG_ON(dev_list != NULL);
325} 282}
326 283
327module_init(init_fdomain_cs); 284module_init(init_fdomain_cs);