aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-04-02 15:49:59 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-04-02 15:49:59 -0400
commit86dca4f8e6ab1fd8a3fb5838163fc9d7990f416e (patch)
tree3d32116afc3be0d323ef93f260592bcea11db329 /drivers/scsi
parent9c8680e2cfbb60d5075f8caaf9d98276120bcc78 (diff)
parent553ee5dc1a7a1fb04a6286b0c779481f7035bbd1 (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/brodo/pcmcia-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/brodo/pcmcia-2.6: (33 commits) [PATCH] pcmcia: declare pccard_iodyn_ops (fix m8xx_pcmcia.c compilation error) [PATCH] pcmcia: fix pcmcia_device_remove oops [PATCH] pcmcia: Add support for Possio GCC AKA PCMCIA Siemens MC45 [PATCH] pcmcia: pseudo device handling update [PATCH] pcmcia: convert DEV_OK to pcmcia_dev_present [PATCH] pcmcia: use bitfield instead of p_state and state [PATCH] pcmcia: remove unused p_dev->state flags [PATCH] pcmcia: make pcmcia_release_{io,irq} static [PATCH] pcmcia: add return value to _config() functions [PATCH] pcmcia: remove dev_link_t and client_handle_t indirection [PATCH] pcmcia: embed dev_link_t into struct pcmcia_device [PATCH] pcmcia: rename pcmcia_device.state [PATCH] pcmcia: remove unneeded Vcc pseudo setting [PATCH] pcmcia: remove export of pcmcia_release_configuration [PATCH] pcmcia: default suspend and resume handling [PATCH] pcmcia: convert remaining users of pcmcia_release_io and _irq [PATCH] pcmcia: add pcmcia_disable_device [PATCH] serial_cs: add Merlin U630 IDs [PATCH] pcmcia: AT91RM9200 Compact Flash driver [PATCH] pcmcia: socket.functions starts with 1 ...
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/pcmcia/aha152x_stub.c112
-rw-r--r--drivers/scsi/pcmcia/fdomain_stub.c155
-rw-r--r--drivers/scsi/pcmcia/nsp_cs.c136
-rw-r--r--drivers/scsi/pcmcia/nsp_cs.h8
-rw-r--r--drivers/scsi/pcmcia/qlogic_stub.c127
-rw-r--r--drivers/scsi/pcmcia/sym53c500_cs.c124
6 files changed, 221 insertions, 441 deletions
diff --git a/drivers/scsi/pcmcia/aha152x_stub.c b/drivers/scsi/pcmcia/aha152x_stub.c
index 5609847e254a..ee449b29fc82 100644
--- a/drivers/scsi/pcmcia/aha152x_stub.c
+++ b/drivers/scsi/pcmcia/aha152x_stub.c
@@ -89,29 +89,29 @@ MODULE_LICENSE("Dual MPL/GPL");
89/*====================================================================*/ 89/*====================================================================*/
90 90
91typedef struct scsi_info_t { 91typedef struct scsi_info_t {
92 dev_link_t link; 92 struct pcmcia_device *p_dev;
93 dev_node_t node; 93 dev_node_t node;
94 struct Scsi_Host *host; 94 struct Scsi_Host *host;
95} scsi_info_t; 95} scsi_info_t;
96 96
97static void aha152x_release_cs(dev_link_t *link); 97static void aha152x_release_cs(struct pcmcia_device *link);
98static void aha152x_detach(struct pcmcia_device *p_dev); 98static void aha152x_detach(struct pcmcia_device *p_dev);
99static void aha152x_config_cs(dev_link_t *link); 99static int aha152x_config_cs(struct pcmcia_device *link);
100 100
101static dev_link_t *dev_list; 101static struct pcmcia_device *dev_list;
102 102
103static int aha152x_attach(struct pcmcia_device *p_dev) 103static int aha152x_probe(struct pcmcia_device *link)
104{ 104{
105 scsi_info_t *info; 105 scsi_info_t *info;
106 dev_link_t *link; 106
107
108 DEBUG(0, "aha152x_attach()\n"); 107 DEBUG(0, "aha152x_attach()\n");
109 108
110 /* Create new SCSI device */ 109 /* Create new SCSI device */
111 info = kmalloc(sizeof(*info), GFP_KERNEL); 110 info = kmalloc(sizeof(*info), GFP_KERNEL);
112 if (!info) return -ENOMEM; 111 if (!info) return -ENOMEM;
113 memset(info, 0, sizeof(*info)); 112 memset(info, 0, sizeof(*info));
114 link = &info->link; link->priv = info; 113 info->p_dev = link;
114 link->priv = info;
115 115
116 link->io.NumPorts1 = 0x20; 116 link->io.NumPorts1 = 0x20;
117 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; 117 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
@@ -119,41 +119,22 @@ static int aha152x_attach(struct pcmcia_device *p_dev)
119 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; 119 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
120 link->irq.IRQInfo1 = IRQ_LEVEL_ID; 120 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
121 link->conf.Attributes = CONF_ENABLE_IRQ; 121 link->conf.Attributes = CONF_ENABLE_IRQ;
122 link->conf.Vcc = 50;
123 link->conf.IntType = INT_MEMORY_AND_IO; 122 link->conf.IntType = INT_MEMORY_AND_IO;
124 link->conf.Present = PRESENT_OPTION; 123 link->conf.Present = PRESENT_OPTION;
125 124
126 link->handle = p_dev; 125 return aha152x_config_cs(link);
127 p_dev->instance = link;
128
129 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
130 aha152x_config_cs(link);
131
132 return 0;
133} /* aha152x_attach */ 126} /* aha152x_attach */
134 127
135/*====================================================================*/ 128/*====================================================================*/
136 129
137static void aha152x_detach(struct pcmcia_device *p_dev) 130static void aha152x_detach(struct pcmcia_device *link)
138{ 131{
139 dev_link_t *link = dev_to_instance(p_dev);
140 dev_link_t **linkp;
141
142 DEBUG(0, "aha152x_detach(0x%p)\n", link); 132 DEBUG(0, "aha152x_detach(0x%p)\n", link);
143
144 /* Locate device structure */
145 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
146 if (*linkp == link) break;
147 if (*linkp == NULL)
148 return;
149 133
150 if (link->state & DEV_CONFIG) 134 aha152x_release_cs(link);
151 aha152x_release_cs(link);
152 135
153 /* Unlink device structure, free bits */ 136 /* Unlink device structure, free bits */
154 *linkp = link->next;
155 kfree(link->priv); 137 kfree(link->priv);
156
157} /* aha152x_detach */ 138} /* aha152x_detach */
158 139
159/*====================================================================*/ 140/*====================================================================*/
@@ -161,9 +142,8 @@ static void aha152x_detach(struct pcmcia_device *p_dev)
161#define CS_CHECK(fn, ret) \ 142#define CS_CHECK(fn, ret) \
162do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) 143do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
163 144
164static void aha152x_config_cs(dev_link_t *link) 145static int aha152x_config_cs(struct pcmcia_device *link)
165{ 146{
166 client_handle_t handle = link->handle;
167 scsi_info_t *info = link->priv; 147 scsi_info_t *info = link->priv;
168 struct aha152x_setup s; 148 struct aha152x_setup s;
169 tuple_t tuple; 149 tuple_t tuple;
@@ -178,19 +158,16 @@ static void aha152x_config_cs(dev_link_t *link)
178 tuple.TupleData = tuple_data; 158 tuple.TupleData = tuple_data;
179 tuple.TupleDataMax = 64; 159 tuple.TupleDataMax = 64;
180 tuple.TupleOffset = 0; 160 tuple.TupleOffset = 0;
181 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); 161 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
182 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); 162 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
183 CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); 163 CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
184 link->conf.ConfigBase = parse.config.base; 164 link->conf.ConfigBase = parse.config.base;
185 165
186 /* Configure card */
187 link->state |= DEV_CONFIG;
188
189 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; 166 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
190 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); 167 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
191 while (1) { 168 while (1) {
192 if (pcmcia_get_tuple_data(handle, &tuple) != 0 || 169 if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
193 pcmcia_parse_tuple(handle, &tuple, &parse) != 0) 170 pcmcia_parse_tuple(link, &tuple, &parse) != 0)
194 goto next_entry; 171 goto next_entry;
195 /* For New Media T&J, look for a SCSI window */ 172 /* For New Media T&J, look for a SCSI window */
196 if (parse.cftable_entry.io.win[0].len >= 0x20) 173 if (parse.cftable_entry.io.win[0].len >= 0x20)
@@ -201,15 +178,15 @@ static void aha152x_config_cs(dev_link_t *link)
201 if ((parse.cftable_entry.io.nwin > 0) && 178 if ((parse.cftable_entry.io.nwin > 0) &&
202 (link->io.BasePort1 < 0xffff)) { 179 (link->io.BasePort1 < 0xffff)) {
203 link->conf.ConfigIndex = parse.cftable_entry.index; 180 link->conf.ConfigIndex = parse.cftable_entry.index;
204 i = pcmcia_request_io(handle, &link->io); 181 i = pcmcia_request_io(link, &link->io);
205 if (i == CS_SUCCESS) break; 182 if (i == CS_SUCCESS) break;
206 } 183 }
207 next_entry: 184 next_entry:
208 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple)); 185 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
209 } 186 }
210 187
211 CS_CHECK(RequestIRQ, pcmcia_request_irq(handle, &link->irq)); 188 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
212 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf)); 189 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
213 190
214 /* Set configuration options for the aha152x driver */ 191 /* Set configuration options for the aha152x driver */
215 memset(&s, 0, sizeof(s)); 192 memset(&s, 0, sizeof(s));
@@ -231,53 +208,30 @@ static void aha152x_config_cs(dev_link_t *link)
231 } 208 }
232 209
233 sprintf(info->node.dev_name, "scsi%d", host->host_no); 210 sprintf(info->node.dev_name, "scsi%d", host->host_no);
234 link->dev = &info->node; 211 link->dev_node = &info->node;
235 info->host = host; 212 info->host = host;
236 213
237 link->state &= ~DEV_CONFIG_PENDING; 214 return 0;
238 return; 215
239
240cs_failed: 216cs_failed:
241 cs_error(link->handle, last_fn, last_ret); 217 cs_error(link, last_fn, last_ret);
242 aha152x_release_cs(link); 218 aha152x_release_cs(link);
243 return; 219 return -ENODEV;
244} 220}
245 221
246static void aha152x_release_cs(dev_link_t *link) 222static void aha152x_release_cs(struct pcmcia_device *link)
247{ 223{
248 scsi_info_t *info = link->priv; 224 scsi_info_t *info = link->priv;
249 225
250 aha152x_release(info->host); 226 aha152x_release(info->host);
251 link->dev = NULL; 227 pcmcia_disable_device(link);
252
253 pcmcia_release_configuration(link->handle);
254 pcmcia_release_io(link->handle, &link->io);
255 pcmcia_release_irq(link->handle, &link->irq);
256
257 link->state &= ~DEV_CONFIG;
258} 228}
259 229
260static int aha152x_suspend(struct pcmcia_device *dev) 230static int aha152x_resume(struct pcmcia_device *link)
261{ 231{
262 dev_link_t *link = dev_to_instance(dev);
263
264 link->state |= DEV_SUSPEND;
265 if (link->state & DEV_CONFIG)
266 pcmcia_release_configuration(link->handle);
267
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; 232 scsi_info_t *info = link->priv;
275 233
276 link->state &= ~DEV_SUSPEND; 234 aha152x_host_reset_host(info->host);
277 if (link->state & DEV_CONFIG) {
278 pcmcia_request_configuration(link->handle, &link->conf);
279 aha152x_host_reset_host(info->host);
280 }
281 235
282 return 0; 236 return 0;
283} 237}
@@ -297,10 +251,9 @@ static struct pcmcia_driver aha152x_cs_driver = {
297 .drv = { 251 .drv = {
298 .name = "aha152x_cs", 252 .name = "aha152x_cs",
299 }, 253 },
300 .probe = aha152x_attach, 254 .probe = aha152x_probe,
301 .remove = aha152x_detach, 255 .remove = aha152x_detach,
302 .id_table = aha152x_ids, 256 .id_table = aha152x_ids,
303 .suspend = aha152x_suspend,
304 .resume = aha152x_resume, 257 .resume = aha152x_resume,
305}; 258};
306 259
@@ -317,4 +270,3 @@ static void __exit exit_aha152x_cs(void)
317 270
318module_init(init_aha152x_cs); 271module_init(init_aha152x_cs);
319module_exit(exit_aha152x_cs); 272module_exit(exit_aha152x_cs);
320
diff --git a/drivers/scsi/pcmcia/fdomain_stub.c b/drivers/scsi/pcmcia/fdomain_stub.c
index 788c58d805f3..85f7ffac19a0 100644
--- a/drivers/scsi/pcmcia/fdomain_stub.c
+++ b/drivers/scsi/pcmcia/fdomain_stub.c
@@ -73,57 +73,48 @@ static char *version =
73/*====================================================================*/ 73/*====================================================================*/
74 74
75typedef struct scsi_info_t { 75typedef struct scsi_info_t {
76 dev_link_t link; 76 struct pcmcia_device *p_dev;
77 dev_node_t node; 77 dev_node_t node;
78 struct Scsi_Host *host; 78 struct Scsi_Host *host;
79} scsi_info_t; 79} scsi_info_t;
80 80
81 81
82static void fdomain_release(dev_link_t *link); 82static void fdomain_release(struct pcmcia_device *link);
83static void fdomain_detach(struct pcmcia_device *p_dev); 83static void fdomain_detach(struct pcmcia_device *p_dev);
84static void fdomain_config(dev_link_t *link); 84static int fdomain_config(struct pcmcia_device *link);
85 85
86static int fdomain_attach(struct pcmcia_device *p_dev) 86static int fdomain_probe(struct pcmcia_device *link)
87{ 87{
88 scsi_info_t *info; 88 scsi_info_t *info;
89 dev_link_t *link; 89
90 90 DEBUG(0, "fdomain_attach()\n");
91 DEBUG(0, "fdomain_attach()\n"); 91
92 92 /* Create new SCSI device */
93 /* Create new SCSI device */ 93 info = kzalloc(sizeof(*info), GFP_KERNEL);
94 info = kmalloc(sizeof(*info), GFP_KERNEL); 94 if (!info)
95 if (!info) return -ENOMEM; 95 return -ENOMEM;
96 memset(info, 0, sizeof(*info)); 96
97 link = &info->link; link->priv = info; 97 info->p_dev = link;
98 link->io.NumPorts1 = 0x10; 98 link->priv = info;
99 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; 99 link->io.NumPorts1 = 0x10;
100 link->io.IOAddrLines = 10; 100 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
101 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; 101 link->io.IOAddrLines = 10;
102 link->irq.IRQInfo1 = IRQ_LEVEL_ID; 102 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
103 link->conf.Attributes = CONF_ENABLE_IRQ; 103 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
104 link->conf.Vcc = 50; 104 link->conf.Attributes = CONF_ENABLE_IRQ;
105 link->conf.IntType = INT_MEMORY_AND_IO; 105 link->conf.IntType = INT_MEMORY_AND_IO;
106 link->conf.Present = PRESENT_OPTION; 106 link->conf.Present = PRESENT_OPTION;
107 107
108 link->handle = p_dev; 108 return fdomain_config(link);
109 p_dev->instance = link;
110
111 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
112 fdomain_config(link);
113
114 return 0;
115} /* fdomain_attach */ 109} /* fdomain_attach */
116 110
117/*====================================================================*/ 111/*====================================================================*/
118 112
119static void fdomain_detach(struct pcmcia_device *p_dev) 113static void fdomain_detach(struct pcmcia_device *link)
120{ 114{
121 dev_link_t *link = dev_to_instance(p_dev);
122
123 DEBUG(0, "fdomain_detach(0x%p)\n", link); 115 DEBUG(0, "fdomain_detach(0x%p)\n", link);
124 116
125 if (link->state & DEV_CONFIG) 117 fdomain_release(link);
126 fdomain_release(link);
127 118
128 kfree(link->priv); 119 kfree(link->priv);
129} /* fdomain_detach */ 120} /* fdomain_detach */
@@ -133,9 +124,8 @@ static void fdomain_detach(struct pcmcia_device *p_dev)
133#define CS_CHECK(fn, ret) \ 124#define CS_CHECK(fn, ret) \
134do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) 125do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
135 126
136static void fdomain_config(dev_link_t *link) 127static int fdomain_config(struct pcmcia_device *link)
137{ 128{
138 client_handle_t handle = link->handle;
139 scsi_info_t *info = link->priv; 129 scsi_info_t *info = link->priv;
140 tuple_t tuple; 130 tuple_t tuple;
141 cisparse_t parse; 131 cisparse_t parse;
@@ -150,103 +140,75 @@ static void fdomain_config(dev_link_t *link)
150 tuple.TupleData = tuple_data; 140 tuple.TupleData = tuple_data;
151 tuple.TupleDataMax = 64; 141 tuple.TupleDataMax = 64;
152 tuple.TupleOffset = 0; 142 tuple.TupleOffset = 0;
153 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); 143 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
154 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); 144 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
155 CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); 145 CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
156 link->conf.ConfigBase = parse.config.base; 146 link->conf.ConfigBase = parse.config.base;
157 147
158 /* Configure card */
159 link->state |= DEV_CONFIG;
160
161 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; 148 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
162 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); 149 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
163 while (1) { 150 while (1) {
164 if (pcmcia_get_tuple_data(handle, &tuple) != 0 || 151 if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
165 pcmcia_parse_tuple(handle, &tuple, &parse) != 0) 152 pcmcia_parse_tuple(link, &tuple, &parse) != 0)
166 goto next_entry; 153 goto next_entry;
167 link->conf.ConfigIndex = parse.cftable_entry.index; 154 link->conf.ConfigIndex = parse.cftable_entry.index;
168 link->io.BasePort1 = parse.cftable_entry.io.win[0].base; 155 link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
169 i = pcmcia_request_io(handle, &link->io); 156 i = pcmcia_request_io(link, &link->io);
170 if (i == CS_SUCCESS) break; 157 if (i == CS_SUCCESS) break;
171 next_entry: 158 next_entry:
172 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple)); 159 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
173 } 160 }
174 161
175 CS_CHECK(RequestIRQ, pcmcia_request_irq(handle, &link->irq)); 162 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
176 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf)); 163 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
177 164
178 /* A bad hack... */ 165 /* A bad hack... */
179 release_region(link->io.BasePort1, link->io.NumPorts1); 166 release_region(link->io.BasePort1, link->io.NumPorts1);
180 167
181 /* Set configuration options for the fdomain driver */ 168 /* Set configuration options for the fdomain driver */
182 sprintf(str, "%d,%d", link->io.BasePort1, link->irq.AssignedIRQ); 169 sprintf(str, "%d,%d", link->io.BasePort1, link->irq.AssignedIRQ);
183 fdomain_setup(str); 170 fdomain_setup(str);
184 171
185 host = __fdomain_16x0_detect(&fdomain_driver_template); 172 host = __fdomain_16x0_detect(&fdomain_driver_template);
186 if (!host) { 173 if (!host) {
187 printk(KERN_INFO "fdomain_cs: no SCSI devices found\n"); 174 printk(KERN_INFO "fdomain_cs: no SCSI devices found\n");
188 goto cs_failed; 175 goto cs_failed;
189 } 176 }
190 177
191 scsi_add_host(host, NULL); /* XXX handle failure */ 178 if (scsi_add_host(host, NULL))
179 goto cs_failed;
192 scsi_scan_host(host); 180 scsi_scan_host(host);
193 181
194 sprintf(info->node.dev_name, "scsi%d", host->host_no); 182 sprintf(info->node.dev_name, "scsi%d", host->host_no);
195 link->dev = &info->node; 183 link->dev_node = &info->node;
196 info->host = host; 184 info->host = host;
197 185
198 link->state &= ~DEV_CONFIG_PENDING; 186 return 0;
199 return; 187
200
201cs_failed: 188cs_failed:
202 cs_error(link->handle, last_fn, last_ret); 189 cs_error(link, last_fn, last_ret);
203 fdomain_release(link); 190 fdomain_release(link);
204 return; 191 return -ENODEV;
205
206} /* fdomain_config */ 192} /* fdomain_config */
207 193
208/*====================================================================*/ 194/*====================================================================*/
209 195
210static void fdomain_release(dev_link_t *link) 196static void fdomain_release(struct pcmcia_device *link)
211{ 197{
212 scsi_info_t *info = link->priv; 198 scsi_info_t *info = link->priv;
213 199
214 DEBUG(0, "fdomain_release(0x%p)\n", link); 200 DEBUG(0, "fdomain_release(0x%p)\n", link);
215 201
216 scsi_remove_host(info->host); 202 scsi_remove_host(info->host);
217 link->dev = NULL; 203 pcmcia_disable_device(link);
218 204 scsi_unregister(info->host);
219 pcmcia_release_configuration(link->handle);
220 pcmcia_release_io(link->handle, &link->io);
221 pcmcia_release_irq(link->handle, &link->irq);
222
223 scsi_unregister(info->host);
224
225 link->state &= ~DEV_CONFIG;
226} 205}
227 206
228/*====================================================================*/ 207/*====================================================================*/
229 208
230static int fdomain_suspend(struct pcmcia_device *dev) 209static int fdomain_resume(struct pcmcia_device *link)
231{ 210{
232 dev_link_t *link = dev_to_instance(dev); 211 fdomain_16x0_bus_reset(NULL);
233
234 link->state |= DEV_SUSPEND;
235 if (link->state & DEV_CONFIG)
236 pcmcia_release_configuration(link->handle);
237
238 return 0;
239}
240
241static int fdomain_resume(struct pcmcia_device *dev)
242{
243 dev_link_t *link = dev_to_instance(dev);
244
245 link->state &= ~DEV_SUSPEND;
246 if (link->state & DEV_CONFIG) {
247 pcmcia_request_configuration(link->handle, &link->conf);
248 fdomain_16x0_bus_reset(NULL);
249 }
250 212
251 return 0; 213 return 0;
252} 214}
@@ -264,10 +226,9 @@ static struct pcmcia_driver fdomain_cs_driver = {
264 .drv = { 226 .drv = {
265 .name = "fdomain_cs", 227 .name = "fdomain_cs",
266 }, 228 },
267 .probe = fdomain_attach, 229 .probe = fdomain_probe,
268 .remove = fdomain_detach, 230 .remove = fdomain_detach,
269 .id_table = fdomain_ids, 231 .id_table = fdomain_ids,
270 .suspend = fdomain_suspend,
271 .resume = fdomain_resume, 232 .resume = fdomain_resume,
272}; 233};
273 234
diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c
index 9e3ab3fd5355..231f9c311c69 100644
--- a/drivers/scsi/pcmcia/nsp_cs.c
+++ b/drivers/scsi/pcmcia/nsp_cs.c
@@ -1593,11 +1593,11 @@ static int nsp_eh_host_reset(Scsi_Cmnd *SCpnt)
1593 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
1594 card insertion event. 1594 card insertion event.
1595======================================================================*/ 1595======================================================================*/
1596static int nsp_cs_attach(struct pcmcia_device *p_dev) 1596static int nsp_cs_probe(struct pcmcia_device *link)
1597{ 1597{
1598 scsi_info_t *info; 1598 scsi_info_t *info;
1599 dev_link_t *link;
1600 nsp_hw_data *data = &nsp_data_base; 1599 nsp_hw_data *data = &nsp_data_base;
1600 int ret;
1601 1601
1602 nsp_dbg(NSP_DEBUG_INIT, "in"); 1602 nsp_dbg(NSP_DEBUG_INIT, "in");
1603 1603
@@ -1605,7 +1605,7 @@ static int nsp_cs_attach(struct pcmcia_device *p_dev)
1605 info = kmalloc(sizeof(*info), GFP_KERNEL); 1605 info = kmalloc(sizeof(*info), GFP_KERNEL);
1606 if (info == NULL) { return -ENOMEM; } 1606 if (info == NULL) { return -ENOMEM; }
1607 memset(info, 0, sizeof(*info)); 1607 memset(info, 0, sizeof(*info));
1608 link = &info->link; 1608 info->p_dev = link;
1609 link->priv = info; 1609 link->priv = info;
1610 data->ScsiInfo = info; 1610 data->ScsiInfo = info;
1611 1611
@@ -1627,18 +1627,13 @@ static int nsp_cs_attach(struct pcmcia_device *p_dev)
1627 1627
1628 /* General socket configuration */ 1628 /* General socket configuration */
1629 link->conf.Attributes = CONF_ENABLE_IRQ; 1629 link->conf.Attributes = CONF_ENABLE_IRQ;
1630 link->conf.Vcc = 50;
1631 link->conf.IntType = INT_MEMORY_AND_IO; 1630 link->conf.IntType = INT_MEMORY_AND_IO;
1632 link->conf.Present = PRESENT_OPTION; 1631 link->conf.Present = PRESENT_OPTION;
1633 1632
1634 link->handle = p_dev; 1633 ret = nsp_cs_config(link);
1635 p_dev->instance = link;
1636
1637 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
1638 nsp_cs_config(link);
1639 1634
1640 nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link); 1635 nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link);
1641 return 0; 1636 return ret;
1642} /* nsp_cs_attach */ 1637} /* nsp_cs_attach */
1643 1638
1644 1639
@@ -1648,16 +1643,12 @@ static int nsp_cs_attach(struct pcmcia_device *p_dev)
1648 structures are freed. Otherwise, the structures will be freed 1643 structures are freed. Otherwise, the structures will be freed
1649 when the device is released. 1644 when the device is released.
1650======================================================================*/ 1645======================================================================*/
1651static void nsp_cs_detach(struct pcmcia_device *p_dev) 1646static void nsp_cs_detach(struct pcmcia_device *link)
1652{ 1647{
1653 dev_link_t *link = dev_to_instance(p_dev);
1654
1655 nsp_dbg(NSP_DEBUG_INIT, "in, link=0x%p", link); 1648 nsp_dbg(NSP_DEBUG_INIT, "in, link=0x%p", link);
1656 1649
1657 if (link->state & DEV_CONFIG) { 1650 ((scsi_info_t *)link->priv)->stop = 1;
1658 ((scsi_info_t *)link->priv)->stop = 1; 1651 nsp_cs_release(link);
1659 nsp_cs_release(link);
1660 }
1661 1652
1662 kfree(link->priv); 1653 kfree(link->priv);
1663 link->priv = NULL; 1654 link->priv = NULL;
@@ -1672,9 +1663,9 @@ static void nsp_cs_detach(struct pcmcia_device *p_dev)
1672#define CS_CHECK(fn, ret) \ 1663#define CS_CHECK(fn, ret) \
1673do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) 1664do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
1674/*====================================================================*/ 1665/*====================================================================*/
1675static void nsp_cs_config(dev_link_t *link) 1666static int nsp_cs_config(struct pcmcia_device *link)
1676{ 1667{
1677 client_handle_t handle = link->handle; 1668 int ret;
1678 scsi_info_t *info = link->priv; 1669 scsi_info_t *info = link->priv;
1679 tuple_t tuple; 1670 tuple_t tuple;
1680 cisparse_t parse; 1671 cisparse_t parse;
@@ -1698,26 +1689,22 @@ static void nsp_cs_config(dev_link_t *link)
1698 tuple.TupleData = tuple_data; 1689 tuple.TupleData = tuple_data;
1699 tuple.TupleDataMax = sizeof(tuple_data); 1690 tuple.TupleDataMax = sizeof(tuple_data);
1700 tuple.TupleOffset = 0; 1691 tuple.TupleOffset = 0;
1701 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); 1692 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
1702 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); 1693 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
1703 CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); 1694 CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
1704 link->conf.ConfigBase = parse.config.base; 1695 link->conf.ConfigBase = parse.config.base;
1705 link->conf.Present = parse.config.rmask[0]; 1696 link->conf.Present = parse.config.rmask[0];
1706 1697
1707 /* Configure card */
1708 link->state |= DEV_CONFIG;
1709
1710 /* Look up the current Vcc */ 1698 /* Look up the current Vcc */
1711 CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf)); 1699 CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &conf));
1712 link->conf.Vcc = conf.Vcc;
1713 1700
1714 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; 1701 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
1715 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); 1702 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
1716 while (1) { 1703 while (1) {
1717 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); 1704 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
1718 1705
1719 if (pcmcia_get_tuple_data(handle, &tuple) != 0 || 1706 if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
1720 pcmcia_parse_tuple(handle, &tuple, &parse) != 0) 1707 pcmcia_parse_tuple(link, &tuple, &parse) != 0)
1721 goto next_entry; 1708 goto next_entry;
1722 1709
1723 if (cfg->flags & CISTPL_CFTABLE_DEFAULT) { dflt = *cfg; } 1710 if (cfg->flags & CISTPL_CFTABLE_DEFAULT) { dflt = *cfg; }
@@ -1743,10 +1730,10 @@ static void nsp_cs_config(dev_link_t *link)
1743 } 1730 }
1744 1731
1745 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) { 1732 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) {
1746 link->conf.Vpp1 = link->conf.Vpp2 = 1733 link->conf.Vpp =
1747 cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; 1734 cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
1748 } else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) { 1735 } else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) {
1749 link->conf.Vpp1 = link->conf.Vpp2 = 1736 link->conf.Vpp =
1750 dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000; 1737 dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
1751 } 1738 }
1752 1739
@@ -1773,7 +1760,7 @@ static void nsp_cs_config(dev_link_t *link)
1773 link->io.NumPorts2 = io->win[1].len; 1760 link->io.NumPorts2 = io->win[1].len;
1774 } 1761 }
1775 /* This reserves IO space but doesn't actually enable it */ 1762 /* This reserves IO space but doesn't actually enable it */
1776 if (pcmcia_request_io(link->handle, &link->io) != 0) 1763 if (pcmcia_request_io(link, &link->io) != 0)
1777 goto next_entry; 1764 goto next_entry;
1778 } 1765 }
1779 1766
@@ -1788,7 +1775,7 @@ static void nsp_cs_config(dev_link_t *link)
1788 req.Size = 0x1000; 1775 req.Size = 0x1000;
1789 } 1776 }
1790 req.AccessSpeed = 0; 1777 req.AccessSpeed = 0;
1791 if (pcmcia_request_window(&link->handle, &req, &link->win) != 0) 1778 if (pcmcia_request_window(&link, &req, &link->win) != 0)
1792 goto next_entry; 1779 goto next_entry;
1793 map.Page = 0; map.CardOffset = mem->win[0].card_addr; 1780 map.Page = 0; map.CardOffset = mem->win[0].card_addr;
1794 if (pcmcia_map_mem_page(link->win, &map) != 0) 1781 if (pcmcia_map_mem_page(link->win, &map) != 0)
@@ -1802,17 +1789,14 @@ static void nsp_cs_config(dev_link_t *link)
1802 1789
1803 next_entry: 1790 next_entry:
1804 nsp_dbg(NSP_DEBUG_INIT, "next"); 1791 nsp_dbg(NSP_DEBUG_INIT, "next");
1805 1792 pcmcia_disable_device(link);
1806 if (link->io.NumPorts1) { 1793 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
1807 pcmcia_release_io(link->handle, &link->io);
1808 }
1809 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple));
1810 } 1794 }
1811 1795
1812 if (link->conf.Attributes & CONF_ENABLE_IRQ) { 1796 if (link->conf.Attributes & CONF_ENABLE_IRQ) {
1813 CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq)); 1797 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
1814 } 1798 }
1815 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf)); 1799 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
1816 1800
1817 if (free_ports) { 1801 if (free_ports) {
1818 if (link->io.BasePort1) { 1802 if (link->io.BasePort1) {
@@ -1854,16 +1838,19 @@ static void nsp_cs_config(dev_link_t *link)
1854 1838
1855 1839
1856#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,74)) 1840#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,74))
1857 scsi_add_host (host, NULL); 1841 ret = scsi_add_host (host, NULL);
1842 if (ret)
1843 goto cs_failed;
1844
1858 scsi_scan_host(host); 1845 scsi_scan_host(host);
1859 1846
1860 snprintf(info->node.dev_name, sizeof(info->node.dev_name), "scsi%d", host->host_no); 1847 snprintf(info->node.dev_name, sizeof(info->node.dev_name), "scsi%d", host->host_no);
1861 link->dev = &info->node; 1848 link->dev_node = &info->node;
1862 info->host = host; 1849 info->host = host;
1863 1850
1864#else 1851#else
1865 nsp_dbg(NSP_DEBUG_INIT, "GET_SCSI_INFO"); 1852 nsp_dbg(NSP_DEBUG_INIT, "GET_SCSI_INFO");
1866 tail = &link->dev; 1853 tail = &link->dev_node;
1867 info->ndev = 0; 1854 info->ndev = 0;
1868 1855
1869 nsp_dbg(NSP_DEBUG_INIT, "host=0x%p", host); 1856 nsp_dbg(NSP_DEBUG_INIT, "host=0x%p", host);
@@ -1908,11 +1895,10 @@ static void nsp_cs_config(dev_link_t *link)
1908#endif 1895#endif
1909 1896
1910 /* Finally, report what we've done */ 1897 /* Finally, report what we've done */
1911 printk(KERN_INFO "nsp_cs: index 0x%02x: Vcc %d.%d", 1898 printk(KERN_INFO "nsp_cs: index 0x%02x: ",
1912 link->conf.ConfigIndex, 1899 link->conf.ConfigIndex);
1913 link->conf.Vcc/10, link->conf.Vcc%10); 1900 if (link->conf.Vpp) {
1914 if (link->conf.Vpp1) { 1901 printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10);
1915 printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10);
1916 } 1902 }
1917 if (link->conf.Attributes & CONF_ENABLE_IRQ) { 1903 if (link->conf.Attributes & CONF_ENABLE_IRQ) {
1918 printk(", irq %d", link->irq.AssignedIRQ); 1904 printk(", irq %d", link->irq.AssignedIRQ);
@@ -1929,15 +1915,14 @@ static void nsp_cs_config(dev_link_t *link)
1929 req.Base+req.Size-1); 1915 req.Base+req.Size-1);
1930 printk("\n"); 1916 printk("\n");
1931 1917
1932 link->state &= ~DEV_CONFIG_PENDING; 1918 return 0;
1933 return;
1934 1919
1935 cs_failed: 1920 cs_failed:
1936 nsp_dbg(NSP_DEBUG_INIT, "config fail"); 1921 nsp_dbg(NSP_DEBUG_INIT, "config fail");
1937 cs_error(link->handle, last_fn, last_ret); 1922 cs_error(link, last_fn, last_ret);
1938 nsp_cs_release(link); 1923 nsp_cs_release(link);
1939 1924
1940 return; 1925 return -ENODEV;
1941} /* nsp_cs_config */ 1926} /* nsp_cs_config */
1942#undef CS_CHECK 1927#undef CS_CHECK
1943 1928
@@ -1947,7 +1932,7 @@ static void nsp_cs_config(dev_link_t *link)
1947 device, and release the PCMCIA configuration. If the device is 1932 device, and release the PCMCIA configuration. If the device is
1948 still open, this will be postponed until it is closed. 1933 still open, this will be postponed until it is closed.
1949======================================================================*/ 1934======================================================================*/
1950static void nsp_cs_release(dev_link_t *link) 1935static void nsp_cs_release(struct pcmcia_device *link)
1951{ 1936{
1952 scsi_info_t *info = link->priv; 1937 scsi_info_t *info = link->priv;
1953 nsp_hw_data *data = NULL; 1938 nsp_hw_data *data = NULL;
@@ -1968,22 +1953,15 @@ static void nsp_cs_release(dev_link_t *link)
1968#else 1953#else
1969 scsi_unregister_host(&nsp_driver_template); 1954 scsi_unregister_host(&nsp_driver_template);
1970#endif 1955#endif
1971 link->dev = NULL; 1956 link->dev_node = NULL;
1972 1957
1973 if (link->win) { 1958 if (link->win) {
1974 if (data != NULL) { 1959 if (data != NULL) {
1975 iounmap((void *)(data->MmioAddress)); 1960 iounmap((void *)(data->MmioAddress));
1976 } 1961 }
1977 pcmcia_release_window(link->win);
1978 }
1979 pcmcia_release_configuration(link->handle);
1980 if (link->io.NumPorts1) {
1981 pcmcia_release_io(link->handle, &link->io);
1982 } 1962 }
1983 if (link->irq.AssignedIRQ) { 1963 pcmcia_disable_device(link);
1984 pcmcia_release_irq(link->handle, &link->irq); 1964
1985 }
1986 link->state &= ~DEV_CONFIG;
1987#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,2)) 1965#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,2))
1988 if (info->host != NULL) { 1966 if (info->host != NULL) {
1989 scsi_host_put(info->host); 1967 scsi_host_put(info->host);
@@ -1991,14 +1969,11 @@ static void nsp_cs_release(dev_link_t *link)
1991#endif 1969#endif
1992} /* nsp_cs_release */ 1970} /* nsp_cs_release */
1993 1971
1994static int nsp_cs_suspend(struct pcmcia_device *dev) 1972static int nsp_cs_suspend(struct pcmcia_device *link)
1995{ 1973{
1996 dev_link_t *link = dev_to_instance(dev);
1997 scsi_info_t *info = link->priv; 1974 scsi_info_t *info = link->priv;
1998 nsp_hw_data *data; 1975 nsp_hw_data *data;
1999 1976
2000 link->state |= DEV_SUSPEND;
2001
2002 nsp_dbg(NSP_DEBUG_INIT, "event: suspend"); 1977 nsp_dbg(NSP_DEBUG_INIT, "event: suspend");
2003 1978
2004 if (info->host != NULL) { 1979 if (info->host != NULL) {
@@ -2011,25 +1986,16 @@ static int nsp_cs_suspend(struct pcmcia_device *dev)
2011 1986
2012 info->stop = 1; 1987 info->stop = 1;
2013 1988
2014 if (link->state & DEV_CONFIG)
2015 pcmcia_release_configuration(link->handle);
2016
2017 return 0; 1989 return 0;
2018} 1990}
2019 1991
2020static int nsp_cs_resume(struct pcmcia_device *dev) 1992static int nsp_cs_resume(struct pcmcia_device *link)
2021{ 1993{
2022 dev_link_t *link = dev_to_instance(dev);
2023 scsi_info_t *info = link->priv; 1994 scsi_info_t *info = link->priv;
2024 nsp_hw_data *data; 1995 nsp_hw_data *data;
2025 1996
2026 nsp_dbg(NSP_DEBUG_INIT, "event: resume"); 1997 nsp_dbg(NSP_DEBUG_INIT, "event: resume");
2027 1998
2028 link->state &= ~DEV_SUSPEND;
2029
2030 if (link->state & DEV_CONFIG)
2031 pcmcia_request_configuration(link->handle, &link->conf);
2032
2033 info->stop = 0; 1999 info->stop = 0;
2034 2000
2035 if (info->host != NULL) { 2001 if (info->host != NULL) {
@@ -2065,7 +2031,7 @@ static struct pcmcia_driver nsp_driver = {
2065 .drv = { 2031 .drv = {
2066 .name = "nsp_cs", 2032 .name = "nsp_cs",
2067 }, 2033 },
2068 .probe = nsp_cs_attach, 2034 .probe = nsp_cs_probe,
2069 .remove = nsp_cs_detach, 2035 .remove = nsp_cs_detach,
2070 .id_table = nsp_cs_ids, 2036 .id_table = nsp_cs_ids,
2071 .suspend = nsp_cs_suspend, 2037 .suspend = nsp_cs_suspend,
@@ -2098,19 +2064,7 @@ static int __init nsp_cs_init(void)
2098static void __exit nsp_cs_exit(void) 2064static void __exit nsp_cs_exit(void)
2099{ 2065{
2100 nsp_msg(KERN_INFO, "unloading..."); 2066 nsp_msg(KERN_INFO, "unloading...");
2101
2102#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68))
2103 pcmcia_unregister_driver(&nsp_driver); 2067 pcmcia_unregister_driver(&nsp_driver);
2104#else
2105 unregister_pcmcia_driver(&dev_info);
2106 /* XXX: this really needs to move into generic code.. */
2107 while (dev_list != NULL) {
2108 if (dev_list->state & DEV_CONFIG) {
2109 nsp_cs_release(dev_list);
2110 }
2111 nsp_cs_detach(dev_list);
2112 }
2113#endif
2114} 2068}
2115 2069
2116 2070
diff --git a/drivers/scsi/pcmcia/nsp_cs.h b/drivers/scsi/pcmcia/nsp_cs.h
index b66b140a745e..8908b8e5b78a 100644
--- a/drivers/scsi/pcmcia/nsp_cs.h
+++ b/drivers/scsi/pcmcia/nsp_cs.h
@@ -225,7 +225,7 @@
225/*====================================================================*/ 225/*====================================================================*/
226 226
227typedef struct scsi_info_t { 227typedef struct scsi_info_t {
228 dev_link_t link; 228 struct pcmcia_device *p_dev;
229 struct Scsi_Host *host; 229 struct Scsi_Host *host;
230#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,74)) 230#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,74))
231 dev_node_t node; 231 dev_node_t node;
@@ -297,8 +297,8 @@ typedef struct _nsp_hw_data {
297 297
298/* Card service functions */ 298/* Card service functions */
299static void nsp_cs_detach (struct pcmcia_device *p_dev); 299static void nsp_cs_detach (struct pcmcia_device *p_dev);
300static void nsp_cs_release(dev_link_t *link); 300static void nsp_cs_release(struct pcmcia_device *link);
301static void nsp_cs_config (dev_link_t *link); 301static int nsp_cs_config (struct pcmcia_device *link);
302 302
303/* Linux SCSI subsystem specific functions */ 303/* Linux SCSI subsystem specific functions */
304static struct Scsi_Host *nsp_detect (struct scsi_host_template *sht); 304static struct Scsi_Host *nsp_detect (struct scsi_host_template *sht);
@@ -450,7 +450,7 @@ static inline struct Scsi_Host *scsi_host_hn_get(unsigned short hostno)
450 return host; 450 return host;
451} 451}
452 452
453static void cs_error(client_handle_t handle, int func, int ret) 453static void cs_error(struct pcmcia_device *handle, int func, int ret)
454{ 454{
455 error_info_t err = { func, ret }; 455 error_info_t err = { func, ret };
456 pcmcia_report_error(handle, &err); 456 pcmcia_report_error(handle, &err);
diff --git a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c
index dce7e687fd4a..86c2ac6ae623 100644
--- a/drivers/scsi/pcmcia/qlogic_stub.c
+++ b/drivers/scsi/pcmcia/qlogic_stub.c
@@ -91,18 +91,18 @@ static struct scsi_host_template qlogicfas_driver_template = {
91/*====================================================================*/ 91/*====================================================================*/
92 92
93typedef struct scsi_info_t { 93typedef struct scsi_info_t {
94 dev_link_t link; 94 struct pcmcia_device *p_dev;
95 dev_node_t node; 95 dev_node_t node;
96 struct Scsi_Host *host; 96 struct Scsi_Host *host;
97 unsigned short manf_id; 97 unsigned short manf_id;
98} scsi_info_t; 98} scsi_info_t;
99 99
100static void qlogic_release(dev_link_t *link); 100static void qlogic_release(struct pcmcia_device *link);
101static void qlogic_detach(struct pcmcia_device *p_dev); 101static void qlogic_detach(struct pcmcia_device *p_dev);
102static void qlogic_config(dev_link_t * link); 102static int qlogic_config(struct pcmcia_device * link);
103 103
104static struct Scsi_Host *qlogic_detect(struct scsi_host_template *host, 104static struct Scsi_Host *qlogic_detect(struct scsi_host_template *host,
105 dev_link_t *link, int qbase, int qlirq) 105 struct pcmcia_device *link, int qbase, int qlirq)
106{ 106{
107 int qltyp; /* type of chip */ 107 int qltyp; /* type of chip */
108 int qinitid; 108 int qinitid;
@@ -156,10 +156,9 @@ free_scsi_host:
156err: 156err:
157 return NULL; 157 return NULL;
158} 158}
159static int qlogic_attach(struct pcmcia_device *p_dev) 159static int qlogic_probe(struct pcmcia_device *link)
160{ 160{
161 scsi_info_t *info; 161 scsi_info_t *info;
162 dev_link_t *link;
163 162
164 DEBUG(0, "qlogic_attach()\n"); 163 DEBUG(0, "qlogic_attach()\n");
165 164
@@ -168,7 +167,7 @@ static int qlogic_attach(struct pcmcia_device *p_dev)
168 if (!info) 167 if (!info)
169 return -ENOMEM; 168 return -ENOMEM;
170 memset(info, 0, sizeof(*info)); 169 memset(info, 0, sizeof(*info));
171 link = &info->link; 170 info->p_dev = link;
172 link->priv = info; 171 link->priv = info;
173 link->io.NumPorts1 = 16; 172 link->io.NumPorts1 = 16;
174 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; 173 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
@@ -176,30 +175,19 @@ static int qlogic_attach(struct pcmcia_device *p_dev)
176 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; 175 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
177 link->irq.IRQInfo1 = IRQ_LEVEL_ID; 176 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
178 link->conf.Attributes = CONF_ENABLE_IRQ; 177 link->conf.Attributes = CONF_ENABLE_IRQ;
179 link->conf.Vcc = 50;
180 link->conf.IntType = INT_MEMORY_AND_IO; 178 link->conf.IntType = INT_MEMORY_AND_IO;
181 link->conf.Present = PRESENT_OPTION; 179 link->conf.Present = PRESENT_OPTION;
182 180
183 link->handle = p_dev; 181 return qlogic_config(link);
184 p_dev->instance = link;
185
186 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
187 qlogic_config(link);
188
189 return 0;
190} /* qlogic_attach */ 182} /* qlogic_attach */
191 183
192/*====================================================================*/ 184/*====================================================================*/
193 185
194static void qlogic_detach(struct pcmcia_device *p_dev) 186static void qlogic_detach(struct pcmcia_device *link)
195{ 187{
196 dev_link_t *link = dev_to_instance(p_dev);
197
198 DEBUG(0, "qlogic_detach(0x%p)\n", link); 188 DEBUG(0, "qlogic_detach(0x%p)\n", link);
199 189
200 if (link->state & DEV_CONFIG) 190 qlogic_release(link);
201 qlogic_release(link);
202
203 kfree(link->priv); 191 kfree(link->priv);
204 192
205} /* qlogic_detach */ 193} /* qlogic_detach */
@@ -209,9 +197,8 @@ static void qlogic_detach(struct pcmcia_device *p_dev)
209#define CS_CHECK(fn, ret) \ 197#define CS_CHECK(fn, ret) \
210do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) 198do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
211 199
212static void qlogic_config(dev_link_t * link) 200static int qlogic_config(struct pcmcia_device * link)
213{ 201{
214 client_handle_t handle = link->handle;
215 scsi_info_t *info = link->priv; 202 scsi_info_t *info = link->priv;
216 tuple_t tuple; 203 tuple_t tuple;
217 cisparse_t parse; 204 cisparse_t parse;
@@ -225,38 +212,35 @@ static void qlogic_config(dev_link_t * link)
225 tuple.TupleDataMax = 64; 212 tuple.TupleDataMax = 64;
226 tuple.TupleOffset = 0; 213 tuple.TupleOffset = 0;
227 tuple.DesiredTuple = CISTPL_CONFIG; 214 tuple.DesiredTuple = CISTPL_CONFIG;
228 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); 215 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
229 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); 216 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
230 CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); 217 CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
231 link->conf.ConfigBase = parse.config.base; 218 link->conf.ConfigBase = parse.config.base;
232 219
233 tuple.DesiredTuple = CISTPL_MANFID; 220 tuple.DesiredTuple = CISTPL_MANFID;
234 if ((pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS) && (pcmcia_get_tuple_data(handle, &tuple) == CS_SUCCESS)) 221 if ((pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) && (pcmcia_get_tuple_data(link, &tuple) == CS_SUCCESS))
235 info->manf_id = le16_to_cpu(tuple.TupleData[0]); 222 info->manf_id = le16_to_cpu(tuple.TupleData[0]);
236 223
237 /* Configure card */
238 link->state |= DEV_CONFIG;
239
240 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; 224 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
241 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); 225 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
242 while (1) { 226 while (1) {
243 if (pcmcia_get_tuple_data(handle, &tuple) != 0 || 227 if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
244 pcmcia_parse_tuple(handle, &tuple, &parse) != 0) 228 pcmcia_parse_tuple(link, &tuple, &parse) != 0)
245 goto next_entry; 229 goto next_entry;
246 link->conf.ConfigIndex = parse.cftable_entry.index; 230 link->conf.ConfigIndex = parse.cftable_entry.index;
247 link->io.BasePort1 = parse.cftable_entry.io.win[0].base; 231 link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
248 link->io.NumPorts1 = parse.cftable_entry.io.win[0].len; 232 link->io.NumPorts1 = parse.cftable_entry.io.win[0].len;
249 if (link->io.BasePort1 != 0) { 233 if (link->io.BasePort1 != 0) {
250 i = pcmcia_request_io(handle, &link->io); 234 i = pcmcia_request_io(link, &link->io);
251 if (i == CS_SUCCESS) 235 if (i == CS_SUCCESS)
252 break; 236 break;
253 } 237 }
254 next_entry: 238 next_entry:
255 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple)); 239 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
256 } 240 }
257 241
258 CS_CHECK(RequestIRQ, pcmcia_request_irq(handle, &link->irq)); 242 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
259 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf)); 243 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
260 244
261 if ((info->manf_id == MANFID_MACNICA) || (info->manf_id == MANFID_PIONEER) || (info->manf_id == 0x0098)) { 245 if ((info->manf_id == MANFID_MACNICA) || (info->manf_id == MANFID_PIONEER) || (info->manf_id == 0x0098)) {
262 /* set ATAcmd */ 246 /* set ATAcmd */
@@ -275,82 +259,54 @@ static void qlogic_config(dev_link_t * link)
275 259
276 if (!host) { 260 if (!host) {
277 printk(KERN_INFO "%s: no SCSI devices found\n", qlogic_name); 261 printk(KERN_INFO "%s: no SCSI devices found\n", qlogic_name);
278 goto out; 262 goto cs_failed;
279 } 263 }
280 264
281 sprintf(info->node.dev_name, "scsi%d", host->host_no); 265 sprintf(info->node.dev_name, "scsi%d", host->host_no);
282 link->dev = &info->node; 266 link->dev_node = &info->node;
283 info->host = host; 267 info->host = host;
284 268
285out: 269 return 0;
286 link->state &= ~DEV_CONFIG_PENDING;
287 return;
288 270
289cs_failed: 271cs_failed:
290 cs_error(link->handle, last_fn, last_ret); 272 cs_error(link, last_fn, last_ret);
291 link->dev = NULL; 273 pcmcia_disable_device(link);
292 pcmcia_release_configuration(link->handle); 274 return -ENODEV;
293 pcmcia_release_io(link->handle, &link->io);
294 pcmcia_release_irq(link->handle, &link->irq);
295 link->state &= ~DEV_CONFIG;
296 return;
297 275
298} /* qlogic_config */ 276} /* qlogic_config */
299 277
300/*====================================================================*/ 278/*====================================================================*/
301 279
302static void qlogic_release(dev_link_t *link) 280static void qlogic_release(struct pcmcia_device *link)
303{ 281{
304 scsi_info_t *info = link->priv; 282 scsi_info_t *info = link->priv;
305 283
306 DEBUG(0, "qlogic_release(0x%p)\n", link); 284 DEBUG(0, "qlogic_release(0x%p)\n", link);
307 285
308 scsi_remove_host(info->host); 286 scsi_remove_host(info->host);
309 link->dev = NULL;
310 287
311 free_irq(link->irq.AssignedIRQ, info->host); 288 free_irq(link->irq.AssignedIRQ, info->host);
312 289 pcmcia_disable_device(link);
313 pcmcia_release_configuration(link->handle);
314 pcmcia_release_io(link->handle, &link->io);
315 pcmcia_release_irq(link->handle, &link->irq);
316 290
317 scsi_host_put(info->host); 291 scsi_host_put(info->host);
318
319 link->state &= ~DEV_CONFIG;
320} 292}
321 293
322/*====================================================================*/ 294/*====================================================================*/
323 295
324static int qlogic_suspend(struct pcmcia_device *dev) 296static int qlogic_resume(struct pcmcia_device *link)
325{ 297{
326 dev_link_t *link = dev_to_instance(dev); 298 scsi_info_t *info = link->priv;
327
328 link->state |= DEV_SUSPEND;
329 if (link->state & DEV_CONFIG)
330 pcmcia_release_configuration(link->handle);
331
332 return 0;
333}
334 299
335static int qlogic_resume(struct pcmcia_device *dev) 300 pcmcia_request_configuration(link, &link->conf);
336{ 301 if ((info->manf_id == MANFID_MACNICA) ||
337 dev_link_t *link = dev_to_instance(dev); 302 (info->manf_id == MANFID_PIONEER) ||
338 303 (info->manf_id == 0x0098)) {
339 link->state &= ~DEV_SUSPEND; 304 outb(0x80, link->io.BasePort1 + 0xd);
340 if (link->state & DEV_CONFIG) { 305 outb(0x24, link->io.BasePort1 + 0x9);
341 scsi_info_t *info = link->priv; 306 outb(0x04, link->io.BasePort1 + 0xd);
342
343 pcmcia_request_configuration(link->handle, &link->conf);
344 if ((info->manf_id == MANFID_MACNICA) ||
345 (info->manf_id == MANFID_PIONEER) ||
346 (info->manf_id == 0x0098)) {
347 outb(0x80, link->io.BasePort1 + 0xd);
348 outb(0x24, link->io.BasePort1 + 0x9);
349 outb(0x04, link->io.BasePort1 + 0xd);
350 }
351 /* Ugggglllyyyy!!! */
352 qlogicfas408_bus_reset(NULL);
353 } 307 }
308 /* Ugggglllyyyy!!! */
309 qlogicfas408_bus_reset(NULL);
354 310
355 return 0; 311 return 0;
356} 312}
@@ -382,10 +338,9 @@ static struct pcmcia_driver qlogic_cs_driver = {
382 .drv = { 338 .drv = {
383 .name = "qlogic_cs", 339 .name = "qlogic_cs",
384 }, 340 },
385 .probe = qlogic_attach, 341 .probe = qlogic_probe,
386 .remove = qlogic_detach, 342 .remove = qlogic_detach,
387 .id_table = qlogic_ids, 343 .id_table = qlogic_ids,
388 .suspend = qlogic_suspend,
389 .resume = qlogic_resume, 344 .resume = qlogic_resume,
390}; 345};
391 346
diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c
index 3a4dd6f5b81f..9f59827707f0 100644
--- a/drivers/scsi/pcmcia/sym53c500_cs.c
+++ b/drivers/scsi/pcmcia/sym53c500_cs.c
@@ -202,7 +202,7 @@ static char *version =
202/* ================================================================== */ 202/* ================================================================== */
203 203
204struct scsi_info_t { 204struct scsi_info_t {
205 dev_link_t link; 205 struct pcmcia_device *p_dev;
206 dev_node_t node; 206 dev_node_t node;
207 struct Scsi_Host *host; 207 struct Scsi_Host *host;
208 unsigned short manf_id; 208 unsigned short manf_id;
@@ -527,7 +527,7 @@ idle_out:
527} 527}
528 528
529static void 529static void
530SYM53C500_release(dev_link_t *link) 530SYM53C500_release(struct pcmcia_device *link)
531{ 531{
532 struct scsi_info_t *info = link->priv; 532 struct scsi_info_t *info = link->priv;
533 struct Scsi_Host *shost = info->host; 533 struct Scsi_Host *shost = info->host;
@@ -550,13 +550,7 @@ SYM53C500_release(dev_link_t *link)
550 if (shost->io_port && shost->n_io_port) 550 if (shost->io_port && shost->n_io_port)
551 release_region(shost->io_port, shost->n_io_port); 551 release_region(shost->io_port, shost->n_io_port);
552 552
553 link->dev = NULL; 553 pcmcia_disable_device(link);
554
555 pcmcia_release_configuration(link->handle);
556 pcmcia_release_io(link->handle, &link->io);
557 pcmcia_release_irq(link->handle, &link->irq);
558
559 link->state &= ~DEV_CONFIG;
560 554
561 scsi_host_put(shost); 555 scsi_host_put(shost);
562} /* SYM53C500_release */ 556} /* SYM53C500_release */
@@ -713,10 +707,9 @@ static struct scsi_host_template sym53c500_driver_template = {
713#define CS_CHECK(fn, ret) \ 707#define CS_CHECK(fn, ret) \
714do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) 708do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
715 709
716static void 710static int
717SYM53C500_config(dev_link_t *link) 711SYM53C500_config(struct pcmcia_device *link)
718{ 712{
719 client_handle_t handle = link->handle;
720 struct scsi_info_t *info = link->priv; 713 struct scsi_info_t *info = link->priv;
721 tuple_t tuple; 714 tuple_t tuple;
722 cisparse_t parse; 715 cisparse_t parse;
@@ -733,40 +726,37 @@ SYM53C500_config(dev_link_t *link)
733 tuple.TupleDataMax = 64; 726 tuple.TupleDataMax = 64;
734 tuple.TupleOffset = 0; 727 tuple.TupleOffset = 0;
735 tuple.DesiredTuple = CISTPL_CONFIG; 728 tuple.DesiredTuple = CISTPL_CONFIG;
736 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); 729 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
737 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); 730 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
738 CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); 731 CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
739 link->conf.ConfigBase = parse.config.base; 732 link->conf.ConfigBase = parse.config.base;
740 733
741 tuple.DesiredTuple = CISTPL_MANFID; 734 tuple.DesiredTuple = CISTPL_MANFID;
742 if ((pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS) && 735 if ((pcmcia_get_first_tuple(link, &tuple) == CS_SUCCESS) &&
743 (pcmcia_get_tuple_data(handle, &tuple) == CS_SUCCESS)) 736 (pcmcia_get_tuple_data(link, &tuple) == CS_SUCCESS))
744 info->manf_id = le16_to_cpu(tuple.TupleData[0]); 737 info->manf_id = le16_to_cpu(tuple.TupleData[0]);
745 738
746 /* Configure card */
747 link->state |= DEV_CONFIG;
748
749 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; 739 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
750 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); 740 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
751 while (1) { 741 while (1) {
752 if (pcmcia_get_tuple_data(handle, &tuple) != 0 || 742 if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
753 pcmcia_parse_tuple(handle, &tuple, &parse) != 0) 743 pcmcia_parse_tuple(link, &tuple, &parse) != 0)
754 goto next_entry; 744 goto next_entry;
755 link->conf.ConfigIndex = parse.cftable_entry.index; 745 link->conf.ConfigIndex = parse.cftable_entry.index;
756 link->io.BasePort1 = parse.cftable_entry.io.win[0].base; 746 link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
757 link->io.NumPorts1 = parse.cftable_entry.io.win[0].len; 747 link->io.NumPorts1 = parse.cftable_entry.io.win[0].len;
758 748
759 if (link->io.BasePort1 != 0) { 749 if (link->io.BasePort1 != 0) {
760 i = pcmcia_request_io(handle, &link->io); 750 i = pcmcia_request_io(link, &link->io);
761 if (i == CS_SUCCESS) 751 if (i == CS_SUCCESS)
762 break; 752 break;
763 } 753 }
764next_entry: 754next_entry:
765 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple)); 755 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
766 } 756 }
767 757
768 CS_CHECK(RequestIRQ, pcmcia_request_irq(handle, &link->irq)); 758 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
769 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf)); 759 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
770 760
771 /* 761 /*
772 * That's the trouble with copying liberally from another driver. 762 * That's the trouble with copying liberally from another driver.
@@ -835,7 +825,7 @@ next_entry:
835 data->fast_pio = USE_FAST_PIO; 825 data->fast_pio = USE_FAST_PIO;
836 826
837 sprintf(info->node.dev_name, "scsi%d", host->host_no); 827 sprintf(info->node.dev_name, "scsi%d", host->host_no);
838 link->dev = &info->node; 828 link->dev_node = &info->node;
839 info->host = host; 829 info->host = host;
840 830
841 if (scsi_add_host(host, NULL)) 831 if (scsi_add_host(host, NULL))
@@ -843,7 +833,7 @@ next_entry:
843 833
844 scsi_scan_host(host); 834 scsi_scan_host(host);
845 835
846 goto out; /* SUCCESS */ 836 return 0;
847 837
848err_free_irq: 838err_free_irq:
849 free_irq(irq_level, host); 839 free_irq(irq_level, host);
@@ -852,74 +842,50 @@ err_free_scsi:
852err_release: 842err_release:
853 release_region(port_base, 0x10); 843 release_region(port_base, 0x10);
854 printk(KERN_INFO "sym53c500_cs: no SCSI devices found\n"); 844 printk(KERN_INFO "sym53c500_cs: no SCSI devices found\n");
855 845 return -ENODEV;
856out:
857 link->state &= ~DEV_CONFIG_PENDING;
858 return;
859 846
860cs_failed: 847cs_failed:
861 cs_error(link->handle, last_fn, last_ret); 848 cs_error(link, last_fn, last_ret);
862 SYM53C500_release(link); 849 SYM53C500_release(link);
863 return; 850 return -ENODEV;
864} /* SYM53C500_config */ 851} /* SYM53C500_config */
865 852
866static int sym53c500_suspend(struct pcmcia_device *dev) 853static int sym53c500_resume(struct pcmcia_device *link)
867{
868 dev_link_t *link = dev_to_instance(dev);
869
870 link->state |= DEV_SUSPEND;
871 if (link->state & DEV_CONFIG)
872 pcmcia_release_configuration(link->handle);
873
874 return 0;
875}
876
877static int sym53c500_resume(struct pcmcia_device *dev)
878{ 854{
879 dev_link_t *link = dev_to_instance(dev);
880 struct scsi_info_t *info = link->priv; 855 struct scsi_info_t *info = link->priv;
881 856
882 link->state &= ~DEV_SUSPEND; 857 /* See earlier comment about manufacturer IDs. */
883 if (link->state & DEV_CONFIG) { 858 if ((info->manf_id == MANFID_MACNICA) ||
884 pcmcia_request_configuration(link->handle, &link->conf); 859 (info->manf_id == MANFID_PIONEER) ||
885 860 (info->manf_id == 0x0098)) {
886 /* See earlier comment about manufacturer IDs. */ 861 outb(0x80, link->io.BasePort1 + 0xd);
887 if ((info->manf_id == MANFID_MACNICA) || 862 outb(0x24, link->io.BasePort1 + 0x9);
888 (info->manf_id == MANFID_PIONEER) || 863 outb(0x04, link->io.BasePort1 + 0xd);
889 (info->manf_id == 0x0098)) {
890 outb(0x80, link->io.BasePort1 + 0xd);
891 outb(0x24, link->io.BasePort1 + 0x9);
892 outb(0x04, link->io.BasePort1 + 0xd);
893 }
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);
899 } 864 }
865 /*
866 * If things don't work after a "resume",
867 * this is a good place to start looking.
868 */
869 SYM53C500_int_host_reset(link->io.BasePort1);
900 870
901 return 0; 871 return 0;
902} 872}
903 873
904static void 874static void
905SYM53C500_detach(struct pcmcia_device *p_dev) 875SYM53C500_detach(struct pcmcia_device *link)
906{ 876{
907 dev_link_t *link = dev_to_instance(p_dev);
908
909 DEBUG(0, "SYM53C500_detach(0x%p)\n", link); 877 DEBUG(0, "SYM53C500_detach(0x%p)\n", link);
910 878
911 if (link->state & DEV_CONFIG) 879 SYM53C500_release(link);
912 SYM53C500_release(link);
913 880
914 kfree(link->priv); 881 kfree(link->priv);
915 link->priv = NULL; 882 link->priv = NULL;
916} /* SYM53C500_detach */ 883} /* SYM53C500_detach */
917 884
918static int 885static int
919SYM53C500_attach(struct pcmcia_device *p_dev) 886SYM53C500_probe(struct pcmcia_device *link)
920{ 887{
921 struct scsi_info_t *info; 888 struct scsi_info_t *info;
922 dev_link_t *link;
923 889
924 DEBUG(0, "SYM53C500_attach()\n"); 890 DEBUG(0, "SYM53C500_attach()\n");
925 891
@@ -928,7 +894,7 @@ SYM53C500_attach(struct pcmcia_device *p_dev)
928 if (!info) 894 if (!info)
929 return -ENOMEM; 895 return -ENOMEM;
930 memset(info, 0, sizeof(*info)); 896 memset(info, 0, sizeof(*info));
931 link = &info->link; 897 info->p_dev = link;
932 link->priv = info; 898 link->priv = info;
933 link->io.NumPorts1 = 16; 899 link->io.NumPorts1 = 16;
934 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; 900 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
@@ -936,17 +902,10 @@ SYM53C500_attach(struct pcmcia_device *p_dev)
936 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; 902 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
937 link->irq.IRQInfo1 = IRQ_LEVEL_ID; 903 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
938 link->conf.Attributes = CONF_ENABLE_IRQ; 904 link->conf.Attributes = CONF_ENABLE_IRQ;
939 link->conf.Vcc = 50;
940 link->conf.IntType = INT_MEMORY_AND_IO; 905 link->conf.IntType = INT_MEMORY_AND_IO;
941 link->conf.Present = PRESENT_OPTION; 906 link->conf.Present = PRESENT_OPTION;
942 907
943 link->handle = p_dev; 908 return SYM53C500_config(link);
944 p_dev->instance = link;
945
946 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
947 SYM53C500_config(link);
948
949 return 0;
950} /* SYM53C500_attach */ 909} /* SYM53C500_attach */
951 910
952MODULE_AUTHOR("Bob Tracy <rct@frus.com>"); 911MODULE_AUTHOR("Bob Tracy <rct@frus.com>");
@@ -966,10 +925,9 @@ static struct pcmcia_driver sym53c500_cs_driver = {
966 .drv = { 925 .drv = {
967 .name = "sym53c500_cs", 926 .name = "sym53c500_cs",
968 }, 927 },
969 .probe = SYM53C500_attach, 928 .probe = SYM53C500_probe,
970 .remove = SYM53C500_detach, 929 .remove = SYM53C500_detach,
971 .id_table = sym53c500_ids, 930 .id_table = sym53c500_ids,
972 .suspend = sym53c500_suspend,
973 .resume = sym53c500_resume, 931 .resume = sym53c500_resume,
974}; 932};
975 933