aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/pcmcia/aha152x_stub.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/pcmcia/aha152x_stub.c')
-rw-r--r--drivers/scsi/pcmcia/aha152x_stub.c112
1 files changed, 32 insertions, 80 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