diff options
Diffstat (limited to 'drivers/scsi/pcmcia/fdomain_stub.c')
-rw-r--r-- | drivers/scsi/pcmcia/fdomain_stub.c | 117 |
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 | ||
82 | static void fdomain_release(dev_link_t *link); | 82 | static void fdomain_release(dev_link_t *link); |
83 | static int fdomain_event(event_t event, int priority, | 83 | static void fdomain_detach(struct pcmcia_device *p_dev); |
84 | event_callback_args_t *args); | 84 | static void fdomain_config(dev_link_t *link); |
85 | 85 | ||
86 | static dev_link_t *fdomain_attach(void); | 86 | static int fdomain_attach(struct pcmcia_device *p_dev) |
87 | static void fdomain_detach(dev_link_t *); | ||
88 | |||
89 | |||
90 | static dev_link_t *dev_list = NULL; | ||
91 | |||
92 | static dev_info_t dev_info = "fdomain_cs"; | ||
93 | |||
94 | static 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 | ||
136 | static void fdomain_detach(dev_link_t *link) | 119 | static 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 | ||
259 | static int fdomain_event(event_t event, int priority, | 230 | static 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 | |||
241 | static 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 | ||
297 | static struct pcmcia_device_id fdomain_ids[] = { | 254 | static 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 | ||
316 | static int __init init_fdomain_cs(void) | 274 | static int __init init_fdomain_cs(void) |
@@ -321,7 +279,6 @@ static int __init init_fdomain_cs(void) | |||
321 | static void __exit exit_fdomain_cs(void) | 279 | static 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 | ||
327 | module_init(init_fdomain_cs); | 284 | module_init(init_fdomain_cs); |