aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/pcmcia
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/pcmcia')
-rw-r--r--drivers/scsi/pcmcia/aha152x_stub.c99
-rw-r--r--drivers/scsi/pcmcia/fdomain_stub.c117
-rw-r--r--drivers/scsi/pcmcia/nsp_cs.c167
-rw-r--r--drivers/scsi/pcmcia/nsp_cs.h4
-rw-r--r--drivers/scsi/pcmcia/qlogic_stub.c127
-rw-r--r--drivers/scsi/pcmcia/sym53c500_cs.c133
6 files changed, 213 insertions, 434 deletions
diff --git a/drivers/scsi/pcmcia/aha152x_stub.c b/drivers/scsi/pcmcia/aha152x_stub.c
index 7c5306499832..0c9edb7051f4 100644
--- a/drivers/scsi/pcmcia/aha152x_stub.c
+++ b/drivers/scsi/pcmcia/aha152x_stub.c
@@ -95,27 +95,21 @@ typedef struct scsi_info_t {
95} scsi_info_t; 95} scsi_info_t;
96 96
97static void aha152x_release_cs(dev_link_t *link); 97static void aha152x_release_cs(dev_link_t *link);
98static int aha152x_event(event_t event, int priority, 98static void aha152x_detach(struct pcmcia_device *p_dev);
99 event_callback_args_t *args); 99static void aha152x_config_cs(dev_link_t *link);
100
101static dev_link_t *aha152x_attach(void);
102static void aha152x_detach(dev_link_t *);
103 100
104static dev_link_t *dev_list; 101static dev_link_t *dev_list;
105static dev_info_t dev_info = "aha152x_cs";
106 102
107static dev_link_t *aha152x_attach(void) 103static int aha152x_attach(struct pcmcia_device *p_dev)
108{ 104{
109 scsi_info_t *info; 105 scsi_info_t *info;
110 client_reg_t client_reg;
111 dev_link_t *link; 106 dev_link_t *link;
112 int ret;
113 107
114 DEBUG(0, "aha152x_attach()\n"); 108 DEBUG(0, "aha152x_attach()\n");
115 109
116 /* Create new SCSI device */ 110 /* Create new SCSI device */
117 info = kmalloc(sizeof(*info), GFP_KERNEL); 111 info = kmalloc(sizeof(*info), GFP_KERNEL);
118 if (!info) return NULL; 112 if (!info) return -ENOMEM;
119 memset(info, 0, sizeof(*info)); 113 memset(info, 0, sizeof(*info));
120 link = &info->link; link->priv = info; 114 link = &info->link; link->priv = info;
121 115
@@ -129,26 +123,20 @@ static dev_link_t *aha152x_attach(void)
129 link->conf.IntType = INT_MEMORY_AND_IO; 123 link->conf.IntType = INT_MEMORY_AND_IO;
130 link->conf.Present = PRESENT_OPTION; 124 link->conf.Present = PRESENT_OPTION;
131 125
132 /* Register with Card Services */ 126 link->handle = p_dev;
133 link->next = dev_list; 127 p_dev->instance = link;
134 dev_list = link; 128
135 client_reg.dev_info = &dev_info; 129 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
136 client_reg.Version = 0x0210; 130 aha152x_config_cs(link);
137 client_reg.event_callback_args.client_data = link; 131
138 ret = pcmcia_register_client(&link->handle, &client_reg); 132 return 0;
139 if (ret != 0) {
140 cs_error(link->handle, RegisterClient, ret);
141 aha152x_detach(link);
142 return NULL;
143 }
144
145 return link;
146} /* aha152x_attach */ 133} /* aha152x_attach */
147 134
148/*====================================================================*/ 135/*====================================================================*/
149 136
150static void aha152x_detach(dev_link_t *link) 137static void aha152x_detach(struct pcmcia_device *p_dev)
151{ 138{
139 dev_link_t *link = dev_to_instance(p_dev);
152 dev_link_t **linkp; 140 dev_link_t **linkp;
153 141
154 DEBUG(0, "aha152x_detach(0x%p)\n", link); 142 DEBUG(0, "aha152x_detach(0x%p)\n", link);
@@ -162,9 +150,6 @@ static void aha152x_detach(dev_link_t *link)
162 if (link->state & DEV_CONFIG) 150 if (link->state & DEV_CONFIG)
163 aha152x_release_cs(link); 151 aha152x_release_cs(link);
164 152
165 if (link->handle)
166 pcmcia_deregister_client(link->handle);
167
168 /* Unlink device structure, free bits */ 153 /* Unlink device structure, free bits */
169 *linkp = link->next; 154 *linkp = link->next;
170 kfree(link->priv); 155 kfree(link->priv);
@@ -272,44 +257,31 @@ static void aha152x_release_cs(dev_link_t *link)
272 link->state &= ~DEV_CONFIG; 257 link->state &= ~DEV_CONFIG;
273} 258}
274 259
275static int aha152x_event(event_t event, int priority, 260static int aha152x_suspend(struct pcmcia_device *dev)
276 event_callback_args_t *args)
277{ 261{
278 dev_link_t *link = args->client_data; 262 dev_link_t *link = dev_to_instance(dev);
279 scsi_info_t *info = link->priv; 263
280
281 DEBUG(0, "aha152x_event(0x%06x)\n", event);
282
283 switch (event) {
284 case CS_EVENT_CARD_REMOVAL:
285 link->state &= ~DEV_PRESENT;
286 if (link->state & DEV_CONFIG)
287 aha152x_release_cs(link);
288 break;
289 case CS_EVENT_CARD_INSERTION:
290 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
291 aha152x_config_cs(link);
292 break;
293 case CS_EVENT_PM_SUSPEND:
294 link->state |= DEV_SUSPEND; 264 link->state |= DEV_SUSPEND;
295 /* Fall through... */
296 case CS_EVENT_RESET_PHYSICAL:
297 if (link->state & DEV_CONFIG) 265 if (link->state & DEV_CONFIG)
298 pcmcia_release_configuration(link->handle); 266 pcmcia_release_configuration(link->handle);
299 break; 267
300 case CS_EVENT_PM_RESUME: 268 return 0;
269}
270
271static int aha152x_resume(struct pcmcia_device *dev)
272{
273 dev_link_t *link = dev_to_instance(dev);
274 scsi_info_t *info = link->priv;
275
301 link->state &= ~DEV_SUSPEND; 276 link->state &= ~DEV_SUSPEND;
302 /* Fall through... */
303 case CS_EVENT_CARD_RESET:
304 if (link->state & DEV_CONFIG) { 277 if (link->state & DEV_CONFIG) {
305 Scsi_Cmnd tmp; 278 Scsi_Cmnd tmp;
306 pcmcia_request_configuration(link->handle, &link->conf); 279 pcmcia_request_configuration(link->handle, &link->conf);
307 tmp.device->host = info->host; 280 tmp.device->host = info->host;
308 aha152x_host_reset(&tmp); 281 aha152x_host_reset(&tmp);
309 } 282 }
310 break; 283
311 } 284 return 0;
312 return 0;
313} 285}
314 286
315static struct pcmcia_device_id aha152x_ids[] = { 287static struct pcmcia_device_id aha152x_ids[] = {
@@ -327,10 +299,11 @@ static struct pcmcia_driver aha152x_cs_driver = {
327 .drv = { 299 .drv = {
328 .name = "aha152x_cs", 300 .name = "aha152x_cs",
329 }, 301 },
330 .attach = aha152x_attach, 302 .probe = aha152x_attach,
331 .event = aha152x_event, 303 .remove = aha152x_detach,
332 .detach = aha152x_detach,
333 .id_table = aha152x_ids, 304 .id_table = aha152x_ids,
305 .suspend = aha152x_suspend,
306 .resume = aha152x_resume,
334}; 307};
335 308
336static int __init init_aha152x_cs(void) 309static int __init init_aha152x_cs(void)
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);
diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c
index 050ea13ff80b..9e3ab3fd5355 100644
--- a/drivers/scsi/pcmcia/nsp_cs.c
+++ b/drivers/scsi/pcmcia/nsp_cs.c
@@ -104,9 +104,6 @@ static struct scsi_host_template nsp_driver_template = {
104#endif 104#endif
105}; 105};
106 106
107static dev_link_t *dev_list = NULL;
108static dev_info_t dev_info = {"nsp_cs"};
109
110static nsp_hw_data nsp_data_base; /* attach <-> detect glue */ 107static nsp_hw_data nsp_data_base; /* attach <-> detect glue */
111 108
112 109
@@ -1596,19 +1593,17 @@ static int nsp_eh_host_reset(Scsi_Cmnd *SCpnt)
1596 configure the card at this point -- we wait until we receive a 1593 configure the card at this point -- we wait until we receive a
1597 card insertion event. 1594 card insertion event.
1598======================================================================*/ 1595======================================================================*/
1599static dev_link_t *nsp_cs_attach(void) 1596static int nsp_cs_attach(struct pcmcia_device *p_dev)
1600{ 1597{
1601 scsi_info_t *info; 1598 scsi_info_t *info;
1602 client_reg_t client_reg;
1603 dev_link_t *link; 1599 dev_link_t *link;
1604 int ret;
1605 nsp_hw_data *data = &nsp_data_base; 1600 nsp_hw_data *data = &nsp_data_base;
1606 1601
1607 nsp_dbg(NSP_DEBUG_INIT, "in"); 1602 nsp_dbg(NSP_DEBUG_INIT, "in");
1608 1603
1609 /* Create new SCSI device */ 1604 /* Create new SCSI device */
1610 info = kmalloc(sizeof(*info), GFP_KERNEL); 1605 info = kmalloc(sizeof(*info), GFP_KERNEL);
1611 if (info == NULL) { return NULL; } 1606 if (info == NULL) { return -ENOMEM; }
1612 memset(info, 0, sizeof(*info)); 1607 memset(info, 0, sizeof(*info));
1613 link = &info->link; 1608 link = &info->link;
1614 link->priv = info; 1609 link->priv = info;
@@ -1636,23 +1631,14 @@ static dev_link_t *nsp_cs_attach(void)
1636 link->conf.IntType = INT_MEMORY_AND_IO; 1631 link->conf.IntType = INT_MEMORY_AND_IO;
1637 link->conf.Present = PRESENT_OPTION; 1632 link->conf.Present = PRESENT_OPTION;
1638 1633
1634 link->handle = p_dev;
1635 p_dev->instance = link;
1639 1636
1640 /* Register with Card Services */ 1637 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
1641 link->next = dev_list; 1638 nsp_cs_config(link);
1642 dev_list = link;
1643 client_reg.dev_info = &dev_info;
1644 client_reg.Version = 0x0210;
1645 client_reg.event_callback_args.client_data = link;
1646 ret = pcmcia_register_client(&link->handle, &client_reg);
1647 if (ret != CS_SUCCESS) {
1648 cs_error(link->handle, RegisterClient, ret);
1649 nsp_cs_detach(link);
1650 return NULL;
1651 }
1652
1653 1639
1654 nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link); 1640 nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link);
1655 return link; 1641 return 0;
1656} /* nsp_cs_attach */ 1642} /* nsp_cs_attach */
1657 1643
1658 1644
@@ -1662,35 +1648,19 @@ static dev_link_t *nsp_cs_attach(void)
1662 structures are freed. Otherwise, the structures will be freed 1648 structures are freed. Otherwise, the structures will be freed
1663 when the device is released. 1649 when the device is released.
1664======================================================================*/ 1650======================================================================*/
1665static void nsp_cs_detach(dev_link_t *link) 1651static void nsp_cs_detach(struct pcmcia_device *p_dev)
1666{ 1652{
1667 dev_link_t **linkp; 1653 dev_link_t *link = dev_to_instance(p_dev);
1668 1654
1669 nsp_dbg(NSP_DEBUG_INIT, "in, link=0x%p", link); 1655 nsp_dbg(NSP_DEBUG_INIT, "in, link=0x%p", link);
1670 1656
1671 /* Locate device structure */ 1657 if (link->state & DEV_CONFIG) {
1672 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) { 1658 ((scsi_info_t *)link->priv)->stop = 1;
1673 if (*linkp == link) {
1674 break;
1675 }
1676 }
1677 if (*linkp == NULL) {
1678 return;
1679 }
1680
1681 if (link->state & DEV_CONFIG)
1682 nsp_cs_release(link); 1659 nsp_cs_release(link);
1683
1684 /* Break the link with Card Services */
1685 if (link->handle) {
1686 pcmcia_deregister_client(link->handle);
1687 } 1660 }
1688 1661
1689 /* Unlink device structure, free bits */
1690 *linkp = link->next;
1691 kfree(link->priv); 1662 kfree(link->priv);
1692 link->priv = NULL; 1663 link->priv = NULL;
1693
1694} /* nsp_cs_detach */ 1664} /* nsp_cs_detach */
1695 1665
1696 1666
@@ -2021,99 +1991,58 @@ static void nsp_cs_release(dev_link_t *link)
2021#endif 1991#endif
2022} /* nsp_cs_release */ 1992} /* nsp_cs_release */
2023 1993
2024/*====================================================================== 1994static int nsp_cs_suspend(struct pcmcia_device *dev)
2025
2026 The card status event handler. Mostly, this schedules other
2027 stuff to run after an event is received. A CARD_REMOVAL event
2028 also sets some flags to discourage the net drivers from trying
2029 to talk to the card any more.
2030
2031 When a CARD_REMOVAL event is received, we immediately set a flag
2032 to block future accesses to this device. All the functions that
2033 actually access the device should check this flag to make sure
2034 the card is still present.
2035
2036======================================================================*/
2037static int nsp_cs_event(event_t event,
2038 int priority,
2039 event_callback_args_t *args)
2040{ 1995{
2041 dev_link_t *link = args->client_data; 1996 dev_link_t *link = dev_to_instance(dev);
2042 scsi_info_t *info = link->priv; 1997 scsi_info_t *info = link->priv;
2043 nsp_hw_data *data; 1998 nsp_hw_data *data;
2044 1999
2045 nsp_dbg(NSP_DEBUG_INIT, "in, event=0x%08x", event); 2000 link->state |= DEV_SUSPEND;
2046 2001
2047 switch (event) { 2002 nsp_dbg(NSP_DEBUG_INIT, "event: suspend");
2048 case CS_EVENT_CARD_REMOVAL:
2049 nsp_dbg(NSP_DEBUG_INIT, "event: remove");
2050 link->state &= ~DEV_PRESENT;
2051 if (link->state & DEV_CONFIG) {
2052 ((scsi_info_t *)link->priv)->stop = 1;
2053 nsp_cs_release(link);
2054 }
2055 break;
2056 2003
2057 case CS_EVENT_CARD_INSERTION: 2004 if (info->host != NULL) {
2058 nsp_dbg(NSP_DEBUG_INIT, "event: insert"); 2005 nsp_msg(KERN_INFO, "clear SDTR status");
2059 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
2060#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,68))
2061 info->bus = args->bus;
2062#endif
2063 nsp_cs_config(link);
2064 break;
2065 2006
2066 case CS_EVENT_PM_SUSPEND: 2007 data = (nsp_hw_data *)info->host->hostdata;
2067 nsp_dbg(NSP_DEBUG_INIT, "event: suspend");
2068 link->state |= DEV_SUSPEND;
2069 /* Fall through... */
2070 case CS_EVENT_RESET_PHYSICAL:
2071 /* Mark the device as stopped, to block IO until later */
2072 nsp_dbg(NSP_DEBUG_INIT, "event: reset physical");
2073 2008
2074 if (info->host != NULL) { 2009 nsphw_init_sync(data);
2075 nsp_msg(KERN_INFO, "clear SDTR status"); 2010 }
2076 2011
2077 data = (nsp_hw_data *)info->host->hostdata; 2012 info->stop = 1;
2078 2013
2079 nsphw_init_sync(data); 2014 if (link->state & DEV_CONFIG)
2080 } 2015 pcmcia_release_configuration(link->handle);
2081 2016
2082 info->stop = 1; 2017 return 0;
2083 if (link->state & DEV_CONFIG) { 2018}
2084 pcmcia_release_configuration(link->handle);
2085 }
2086 break;
2087 2019
2088 case CS_EVENT_PM_RESUME: 2020static int nsp_cs_resume(struct pcmcia_device *dev)
2089 nsp_dbg(NSP_DEBUG_INIT, "event: resume"); 2021{
2090 link->state &= ~DEV_SUSPEND; 2022 dev_link_t *link = dev_to_instance(dev);
2091 /* Fall through... */ 2023 scsi_info_t *info = link->priv;
2092 case CS_EVENT_CARD_RESET: 2024 nsp_hw_data *data;
2093 nsp_dbg(NSP_DEBUG_INIT, "event: reset");
2094 if (link->state & DEV_CONFIG) {
2095 pcmcia_request_configuration(link->handle, &link->conf);
2096 }
2097 info->stop = 0;
2098 2025
2099 if (info->host != NULL) { 2026 nsp_dbg(NSP_DEBUG_INIT, "event: resume");
2100 nsp_msg(KERN_INFO, "reset host and bus");
2101 2027
2102 data = (nsp_hw_data *)info->host->hostdata; 2028 link->state &= ~DEV_SUSPEND;
2103 2029
2104 nsphw_init (data); 2030 if (link->state & DEV_CONFIG)
2105 nsp_bus_reset(data); 2031 pcmcia_request_configuration(link->handle, &link->conf);
2106 }
2107 2032
2108 break; 2033 info->stop = 0;
2109 2034
2110 default: 2035 if (info->host != NULL) {
2111 nsp_dbg(NSP_DEBUG_INIT, "event: unknown"); 2036 nsp_msg(KERN_INFO, "reset host and bus");
2112 break; 2037
2038 data = (nsp_hw_data *)info->host->hostdata;
2039
2040 nsphw_init (data);
2041 nsp_bus_reset(data);
2113 } 2042 }
2114 nsp_dbg(NSP_DEBUG_INIT, "end"); 2043
2115 return 0; 2044 return 0;
2116} /* nsp_cs_event */ 2045}
2117 2046
2118/*======================================================================* 2047/*======================================================================*
2119 * module entry point 2048 * module entry point
@@ -2136,10 +2065,11 @@ static struct pcmcia_driver nsp_driver = {
2136 .drv = { 2065 .drv = {
2137 .name = "nsp_cs", 2066 .name = "nsp_cs",
2138 }, 2067 },
2139 .attach = nsp_cs_attach, 2068 .probe = nsp_cs_attach,
2140 .event = nsp_cs_event, 2069 .remove = nsp_cs_detach,
2141 .detach = nsp_cs_detach,
2142 .id_table = nsp_cs_ids, 2070 .id_table = nsp_cs_ids,
2071 .suspend = nsp_cs_suspend,
2072 .resume = nsp_cs_resume,
2143}; 2073};
2144#endif 2074#endif
2145 2075
@@ -2171,7 +2101,6 @@ static void __exit nsp_cs_exit(void)
2171 2101
2172#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68)) 2102#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68))
2173 pcmcia_unregister_driver(&nsp_driver); 2103 pcmcia_unregister_driver(&nsp_driver);
2174 BUG_ON(dev_list != NULL);
2175#else 2104#else
2176 unregister_pcmcia_driver(&dev_info); 2105 unregister_pcmcia_driver(&dev_info);
2177 /* XXX: this really needs to move into generic code.. */ 2106 /* XXX: this really needs to move into generic code.. */
diff --git a/drivers/scsi/pcmcia/nsp_cs.h b/drivers/scsi/pcmcia/nsp_cs.h
index f8b943082717..b66b140a745e 100644
--- a/drivers/scsi/pcmcia/nsp_cs.h
+++ b/drivers/scsi/pcmcia/nsp_cs.h
@@ -296,11 +296,9 @@ typedef struct _nsp_hw_data {
296 */ 296 */
297 297
298/* Card service functions */ 298/* Card service functions */
299static dev_link_t *nsp_cs_attach (void); 299static void nsp_cs_detach (struct pcmcia_device *p_dev);
300static void nsp_cs_detach (dev_link_t *link);
301static void nsp_cs_release(dev_link_t *link); 300static void nsp_cs_release(dev_link_t *link);
302static void nsp_cs_config (dev_link_t *link); 301static void nsp_cs_config (dev_link_t *link);
303static int nsp_cs_event (event_t event, int priority, event_callback_args_t *args);
304 302
305/* Linux SCSI subsystem specific functions */ 303/* Linux SCSI subsystem specific functions */
306static struct Scsi_Host *nsp_detect (struct scsi_host_template *sht); 304static struct Scsi_Host *nsp_detect (struct scsi_host_template *sht);
diff --git a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c
index bb091a45a880..dce7e687fd4a 100644
--- a/drivers/scsi/pcmcia/qlogic_stub.c
+++ b/drivers/scsi/pcmcia/qlogic_stub.c
@@ -98,15 +98,8 @@ typedef struct scsi_info_t {
98} scsi_info_t; 98} scsi_info_t;
99 99
100static void qlogic_release(dev_link_t *link); 100static void qlogic_release(dev_link_t *link);
101static int qlogic_event(event_t event, int priority, event_callback_args_t * args); 101static void qlogic_detach(struct pcmcia_device *p_dev);
102 102static void qlogic_config(dev_link_t * link);
103static dev_link_t *qlogic_attach(void);
104static void qlogic_detach(dev_link_t *);
105
106
107static dev_link_t *dev_list = NULL;
108
109static dev_info_t dev_info = "qlogic_cs";
110 103
111static struct Scsi_Host *qlogic_detect(struct scsi_host_template *host, 104static struct Scsi_Host *qlogic_detect(struct scsi_host_template *host,
112 dev_link_t *link, int qbase, int qlirq) 105 dev_link_t *link, int qbase, int qlirq)
@@ -163,19 +156,17 @@ free_scsi_host:
163err: 156err:
164 return NULL; 157 return NULL;
165} 158}
166static dev_link_t *qlogic_attach(void) 159static int qlogic_attach(struct pcmcia_device *p_dev)
167{ 160{
168 scsi_info_t *info; 161 scsi_info_t *info;
169 client_reg_t client_reg;
170 dev_link_t *link; 162 dev_link_t *link;
171 int ret;
172 163
173 DEBUG(0, "qlogic_attach()\n"); 164 DEBUG(0, "qlogic_attach()\n");
174 165
175 /* Create new SCSI device */ 166 /* Create new SCSI device */
176 info = kmalloc(sizeof(*info), GFP_KERNEL); 167 info = kmalloc(sizeof(*info), GFP_KERNEL);
177 if (!info) 168 if (!info)
178 return NULL; 169 return -ENOMEM;
179 memset(info, 0, sizeof(*info)); 170 memset(info, 0, sizeof(*info));
180 link = &info->link; 171 link = &info->link;
181 link->priv = info; 172 link->priv = info;
@@ -189,45 +180,26 @@ static dev_link_t *qlogic_attach(void)
189 link->conf.IntType = INT_MEMORY_AND_IO; 180 link->conf.IntType = INT_MEMORY_AND_IO;
190 link->conf.Present = PRESENT_OPTION; 181 link->conf.Present = PRESENT_OPTION;
191 182
192 /* Register with Card Services */ 183 link->handle = p_dev;
193 link->next = dev_list; 184 p_dev->instance = link;
194 dev_list = link;
195 client_reg.dev_info = &dev_info;
196 client_reg.Version = 0x0210;
197 client_reg.event_callback_args.client_data = link;
198 ret = pcmcia_register_client(&link->handle, &client_reg);
199 if (ret != 0) {
200 cs_error(link->handle, RegisterClient, ret);
201 qlogic_detach(link);
202 return NULL;
203 }
204 185
205 return link; 186 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
187 qlogic_config(link);
188
189 return 0;
206} /* qlogic_attach */ 190} /* qlogic_attach */
207 191
208/*====================================================================*/ 192/*====================================================================*/
209 193
210static void qlogic_detach(dev_link_t * link) 194static void qlogic_detach(struct pcmcia_device *p_dev)
211{ 195{
212 dev_link_t **linkp; 196 dev_link_t *link = dev_to_instance(p_dev);
213 197
214 DEBUG(0, "qlogic_detach(0x%p)\n", link); 198 DEBUG(0, "qlogic_detach(0x%p)\n", link);
215 199
216 /* Locate device structure */
217 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
218 if (*linkp == link)
219 break;
220 if (*linkp == NULL)
221 return;
222
223 if (link->state & DEV_CONFIG) 200 if (link->state & DEV_CONFIG)
224 qlogic_release(link); 201 qlogic_release(link);
225 202
226 if (link->handle)
227 pcmcia_deregister_client(link->handle);
228
229 /* Unlink device structure, free bits */
230 *linkp = link->next;
231 kfree(link->priv); 203 kfree(link->priv);
232 204
233} /* qlogic_detach */ 205} /* qlogic_detach */
@@ -349,48 +321,39 @@ static void qlogic_release(dev_link_t *link)
349 321
350/*====================================================================*/ 322/*====================================================================*/
351 323
352static int qlogic_event(event_t event, int priority, event_callback_args_t * args) 324static int qlogic_suspend(struct pcmcia_device *dev)
353{ 325{
354 dev_link_t *link = args->client_data; 326 dev_link_t *link = dev_to_instance(dev);
355 327
356 DEBUG(1, "qlogic_event(0x%06x)\n", event); 328 link->state |= DEV_SUSPEND;
357 329 if (link->state & DEV_CONFIG)
358 switch (event) { 330 pcmcia_release_configuration(link->handle);
359 case CS_EVENT_CARD_REMOVAL: 331
360 link->state &= ~DEV_PRESENT; 332 return 0;
361 if (link->state & DEV_CONFIG) 333}
362 qlogic_release(link); 334
363 break; 335static int qlogic_resume(struct pcmcia_device *dev)
364 case CS_EVENT_CARD_INSERTION: 336{
365 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 337 dev_link_t *link = dev_to_instance(dev);
366 qlogic_config(link); 338
367 break; 339 link->state &= ~DEV_SUSPEND;
368 case CS_EVENT_PM_SUSPEND: 340 if (link->state & DEV_CONFIG) {
369 link->state |= DEV_SUSPEND; 341 scsi_info_t *info = link->priv;
370 /* Fall through... */ 342
371 case CS_EVENT_RESET_PHYSICAL: 343 pcmcia_request_configuration(link->handle, &link->conf);
372 if (link->state & DEV_CONFIG) 344 if ((info->manf_id == MANFID_MACNICA) ||
373 pcmcia_release_configuration(link->handle); 345 (info->manf_id == MANFID_PIONEER) ||
374 break; 346 (info->manf_id == 0x0098)) {
375 case CS_EVENT_PM_RESUME: 347 outb(0x80, link->io.BasePort1 + 0xd);
376 link->state &= ~DEV_SUSPEND; 348 outb(0x24, link->io.BasePort1 + 0x9);
377 /* Fall through... */ 349 outb(0x04, link->io.BasePort1 + 0xd);
378 case CS_EVENT_CARD_RESET:
379 if (link->state & DEV_CONFIG) {
380 scsi_info_t *info = link->priv;
381 pcmcia_request_configuration(link->handle, &link->conf);
382 if ((info->manf_id == MANFID_MACNICA) || (info->manf_id == MANFID_PIONEER) || (info->manf_id == 0x0098)) {
383 outb(0x80, link->io.BasePort1 + 0xd);
384 outb(0x24, link->io.BasePort1 + 0x9);
385 outb(0x04, link->io.BasePort1 + 0xd);
386 }
387 /* Ugggglllyyyy!!! */
388 qlogicfas408_bus_reset(NULL);
389 } 350 }
390 break; 351 /* Ugggglllyyyy!!! */
352 qlogicfas408_bus_reset(NULL);
391 } 353 }
354
392 return 0; 355 return 0;
393} /* qlogic_event */ 356}
394 357
395static struct pcmcia_device_id qlogic_ids[] = { 358static struct pcmcia_device_id qlogic_ids[] = {
396 PCMCIA_DEVICE_PROD_ID12("EIger Labs", "PCMCIA-to-SCSI Adapter", 0x88395fa7, 0x33b7a5e6), 359 PCMCIA_DEVICE_PROD_ID12("EIger Labs", "PCMCIA-to-SCSI Adapter", 0x88395fa7, 0x33b7a5e6),
@@ -419,10 +382,11 @@ static struct pcmcia_driver qlogic_cs_driver = {
419 .drv = { 382 .drv = {
420 .name = "qlogic_cs", 383 .name = "qlogic_cs",
421 }, 384 },
422 .attach = qlogic_attach, 385 .probe = qlogic_attach,
423 .event = qlogic_event, 386 .remove = qlogic_detach,
424 .detach = qlogic_detach,
425 .id_table = qlogic_ids, 387 .id_table = qlogic_ids,
388 .suspend = qlogic_suspend,
389 .resume = qlogic_resume,
426}; 390};
427 391
428static int __init init_qlogic_cs(void) 392static int __init init_qlogic_cs(void)
@@ -433,7 +397,6 @@ static int __init init_qlogic_cs(void)
433static void __exit exit_qlogic_cs(void) 397static void __exit exit_qlogic_cs(void)
434{ 398{
435 pcmcia_unregister_driver(&qlogic_cs_driver); 399 pcmcia_unregister_driver(&qlogic_cs_driver);
436 BUG_ON(dev_list != NULL);
437} 400}
438 401
439MODULE_AUTHOR("Tom Zerucha, Michael Griffith"); 402MODULE_AUTHOR("Tom Zerucha, Michael Griffith");
diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c
index 98b64b2aa8ee..3a4dd6f5b81f 100644
--- a/drivers/scsi/pcmcia/sym53c500_cs.c
+++ b/drivers/scsi/pcmcia/sym53c500_cs.c
@@ -228,15 +228,6 @@ enum Phase {
228 228
229/* ================================================================== */ 229/* ================================================================== */
230 230
231/*
232* Global (within this module) variables other than
233* sym53c500_driver_template (the scsi_host_template).
234*/
235static dev_link_t *dev_list;
236static dev_info_t dev_info = "sym53c500_cs";
237
238/* ================================================================== */
239
240static void 231static void
241chip_init(int io_port) 232chip_init(int io_port)
242{ 233{
@@ -872,96 +863,70 @@ cs_failed:
872 return; 863 return;
873} /* SYM53C500_config */ 864} /* SYM53C500_config */
874 865
875static int 866static int sym53c500_suspend(struct pcmcia_device *dev)
876SYM53C500_event(event_t event, int priority, event_callback_args_t *args)
877{ 867{
878 dev_link_t *link = args->client_data; 868 dev_link_t *link = dev_to_instance(dev);
879 struct scsi_info_t *info = link->priv;
880 869
881 DEBUG(1, "SYM53C500_event(0x%06x)\n", event); 870 link->state |= DEV_SUSPEND;
871 if (link->state & DEV_CONFIG)
872 pcmcia_release_configuration(link->handle);
882 873
883 switch (event) { 874 return 0;
884 case CS_EVENT_CARD_REMOVAL: 875}
885 link->state &= ~DEV_PRESENT; 876
886 if (link->state & DEV_CONFIG) 877static int sym53c500_resume(struct pcmcia_device *dev)
887 SYM53C500_release(link); 878{
888 break; 879 dev_link_t *link = dev_to_instance(dev);
889 case CS_EVENT_CARD_INSERTION: 880 struct scsi_info_t *info = link->priv;
890 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 881
891 SYM53C500_config(link); 882 link->state &= ~DEV_SUSPEND;
892 break; 883 if (link->state & DEV_CONFIG) {
893 case CS_EVENT_PM_SUSPEND: 884 pcmcia_request_configuration(link->handle, &link->conf);
894 link->state |= DEV_SUSPEND; 885
895 /* Fall through... */ 886 /* See earlier comment about manufacturer IDs. */
896 case CS_EVENT_RESET_PHYSICAL: 887 if ((info->manf_id == MANFID_MACNICA) ||
897 if (link->state & DEV_CONFIG) 888 (info->manf_id == MANFID_PIONEER) ||
898 pcmcia_release_configuration(link->handle); 889 (info->manf_id == 0x0098)) {
899 break; 890 outb(0x80, link->io.BasePort1 + 0xd);
900 case CS_EVENT_PM_RESUME: 891 outb(0x24, link->io.BasePort1 + 0x9);
901 link->state &= ~DEV_SUSPEND; 892 outb(0x04, link->io.BasePort1 + 0xd);
902 /* Fall through... */
903 case CS_EVENT_CARD_RESET:
904 if (link->state & DEV_CONFIG) {
905 pcmcia_request_configuration(link->handle, &link->conf);
906 /* See earlier comment about manufacturer IDs. */
907 if ((info->manf_id == MANFID_MACNICA) ||
908 (info->manf_id == MANFID_PIONEER) ||
909 (info->manf_id == 0x0098)) {
910 outb(0x80, link->io.BasePort1 + 0xd);
911 outb(0x24, link->io.BasePort1 + 0x9);
912 outb(0x04, link->io.BasePort1 + 0xd);
913 }
914 /*
915 * If things don't work after a "resume",
916 * this is a good place to start looking.
917 */
918 SYM53C500_int_host_reset(link->io.BasePort1);
919 } 893 }
920 break; 894 /*
895 * If things don't work after a "resume",
896 * this is a good place to start looking.
897 */
898 SYM53C500_int_host_reset(link->io.BasePort1);
921 } 899 }
900
922 return 0; 901 return 0;
923} /* SYM53C500_event */ 902}
924 903
925static void 904static void
926SYM53C500_detach(dev_link_t *link) 905SYM53C500_detach(struct pcmcia_device *p_dev)
927{ 906{
928 dev_link_t **linkp; 907 dev_link_t *link = dev_to_instance(p_dev);
929 908
930 DEBUG(0, "SYM53C500_detach(0x%p)\n", link); 909 DEBUG(0, "SYM53C500_detach(0x%p)\n", link);
931 910
932 /* Locate device structure */
933 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
934 if (*linkp == link)
935 break;
936 if (*linkp == NULL)
937 return;
938
939 if (link->state & DEV_CONFIG) 911 if (link->state & DEV_CONFIG)
940 SYM53C500_release(link); 912 SYM53C500_release(link);
941 913
942 if (link->handle)
943 pcmcia_deregister_client(link->handle);
944
945 /* Unlink device structure, free bits. */
946 *linkp = link->next;
947 kfree(link->priv); 914 kfree(link->priv);
948 link->priv = NULL; 915 link->priv = NULL;
949} /* SYM53C500_detach */ 916} /* SYM53C500_detach */
950 917
951static dev_link_t * 918static int
952SYM53C500_attach(void) 919SYM53C500_attach(struct pcmcia_device *p_dev)
953{ 920{
954 struct scsi_info_t *info; 921 struct scsi_info_t *info;
955 client_reg_t client_reg;
956 dev_link_t *link; 922 dev_link_t *link;
957 int ret;
958 923
959 DEBUG(0, "SYM53C500_attach()\n"); 924 DEBUG(0, "SYM53C500_attach()\n");
960 925
961 /* Create new SCSI device */ 926 /* Create new SCSI device */
962 info = kmalloc(sizeof(*info), GFP_KERNEL); 927 info = kmalloc(sizeof(*info), GFP_KERNEL);
963 if (!info) 928 if (!info)
964 return NULL; 929 return -ENOMEM;
965 memset(info, 0, sizeof(*info)); 930 memset(info, 0, sizeof(*info));
966 link = &info->link; 931 link = &info->link;
967 link->priv = info; 932 link->priv = info;
@@ -975,20 +940,13 @@ SYM53C500_attach(void)
975 link->conf.IntType = INT_MEMORY_AND_IO; 940 link->conf.IntType = INT_MEMORY_AND_IO;
976 link->conf.Present = PRESENT_OPTION; 941 link->conf.Present = PRESENT_OPTION;
977 942
978 /* Register with Card Services */ 943 link->handle = p_dev;
979 link->next = dev_list; 944 p_dev->instance = link;
980 dev_list = link; 945
981 client_reg.dev_info = &dev_info; 946 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
982 client_reg.Version = 0x0210; 947 SYM53C500_config(link);
983 client_reg.event_callback_args.client_data = link;
984 ret = pcmcia_register_client(&link->handle, &client_reg);
985 if (ret != 0) {
986 cs_error(link->handle, RegisterClient, ret);
987 SYM53C500_detach(link);
988 return NULL;
989 }
990 948
991 return link; 949 return 0;
992} /* SYM53C500_attach */ 950} /* SYM53C500_attach */
993 951
994MODULE_AUTHOR("Bob Tracy <rct@frus.com>"); 952MODULE_AUTHOR("Bob Tracy <rct@frus.com>");
@@ -1008,10 +966,11 @@ static struct pcmcia_driver sym53c500_cs_driver = {
1008 .drv = { 966 .drv = {
1009 .name = "sym53c500_cs", 967 .name = "sym53c500_cs",
1010 }, 968 },
1011 .attach = SYM53C500_attach, 969 .probe = SYM53C500_attach,
1012 .event = SYM53C500_event, 970 .remove = SYM53C500_detach,
1013 .detach = SYM53C500_detach,
1014 .id_table = sym53c500_ids, 971 .id_table = sym53c500_ids,
972 .suspend = sym53c500_suspend,
973 .resume = sym53c500_resume,
1015}; 974};
1016 975
1017static int __init 976static int __init