aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial
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/serial
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/serial')
-rw-r--r--drivers/serial/serial_cs.c229
1 files changed, 112 insertions, 117 deletions
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index c30333694fde..2c70773543e0 100644
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -41,6 +41,7 @@
41#include <linux/string.h> 41#include <linux/string.h>
42#include <linux/timer.h> 42#include <linux/timer.h>
43#include <linux/serial_core.h> 43#include <linux/serial_core.h>
44#include <linux/delay.h>
44#include <linux/major.h> 45#include <linux/major.h>
45#include <asm/io.h> 46#include <asm/io.h>
46#include <asm/system.h> 47#include <asm/system.h>
@@ -97,11 +98,13 @@ static const struct multi_id multi_id[] = {
97#define MULTI_COUNT (sizeof(multi_id)/sizeof(struct multi_id)) 98#define MULTI_COUNT (sizeof(multi_id)/sizeof(struct multi_id))
98 99
99struct serial_info { 100struct serial_info {
100 dev_link_t link; 101 struct pcmcia_device *p_dev;
101 int ndev; 102 int ndev;
102 int multi; 103 int multi;
103 int slave; 104 int slave;
104 int manfid; 105 int manfid;
106 int prodid;
107 int c950ctrl;
105 dev_node_t node[4]; 108 dev_node_t node[4];
106 int line[4]; 109 int line[4];
107}; 110};
@@ -113,9 +116,36 @@ struct serial_cfg_mem {
113}; 116};
114 117
115 118
116static void serial_config(dev_link_t * link); 119static int serial_config(struct pcmcia_device * link);
117 120
118 121
122static void wakeup_card(struct serial_info *info)
123{
124 int ctrl = info->c950ctrl;
125
126 if (info->manfid == MANFID_OXSEMI) {
127 outb(12, ctrl + 1);
128 } else if (info->manfid == MANFID_POSSIO && info->prodid == PRODID_POSSIO_GCC) {
129 /* request_region? oxsemi branch does no request_region too... */
130 /* This sequence is needed to properly initialize MC45 attached to OXCF950.
131 * I tried decreasing these msleep()s, but it worked properly (survived
132 * 1000 stop/start operations) with these timeouts (or bigger). */
133 outb(0xA, ctrl + 1);
134 msleep(100);
135 outb(0xE, ctrl + 1);
136 msleep(300);
137 outb(0xC, ctrl + 1);
138 msleep(100);
139 outb(0xE, ctrl + 1);
140 msleep(200);
141 outb(0xF, ctrl + 1);
142 msleep(100);
143 outb(0xE, ctrl + 1);
144 msleep(100);
145 outb(0xC, ctrl + 1);
146 }
147}
148
119/*====================================================================== 149/*======================================================================
120 150
121 After a card is removed, serial_remove() will unregister 151 After a card is removed, serial_remove() will unregister
@@ -123,67 +153,45 @@ static void serial_config(dev_link_t * link);
123 153
124======================================================================*/ 154======================================================================*/
125 155
126static void serial_remove(dev_link_t *link) 156static void serial_remove(struct pcmcia_device *link)
127{ 157{
128 struct serial_info *info = link->priv; 158 struct serial_info *info = link->priv;
129 int i; 159 int i;
130 160
131 link->state &= ~DEV_PRESENT;
132
133 DEBUG(0, "serial_release(0x%p)\n", link); 161 DEBUG(0, "serial_release(0x%p)\n", link);
134 162
135 /* 163 /*
136 * Recheck to see if the device is still configured. 164 * Recheck to see if the device is still configured.
137 */ 165 */
138 if (info->link.state & DEV_CONFIG) { 166 for (i = 0; i < info->ndev; i++)
139 for (i = 0; i < info->ndev; i++) 167 serial8250_unregister_port(info->line[i]);
140 serial8250_unregister_port(info->line[i]);
141 168
142 info->link.dev = NULL; 169 info->p_dev->dev_node = NULL;
143 170
144 if (!info->slave) { 171 if (!info->slave)
145 pcmcia_release_configuration(info->link.handle); 172 pcmcia_disable_device(link);
146 pcmcia_release_io(info->link.handle, &info->link.io);
147 pcmcia_release_irq(info->link.handle, &info->link.irq);
148 }
149
150 info->link.state &= ~DEV_CONFIG;
151 }
152} 173}
153 174
154static int serial_suspend(struct pcmcia_device *dev) 175static int serial_suspend(struct pcmcia_device *link)
155{ 176{
156 dev_link_t *link = dev_to_instance(dev); 177 struct serial_info *info = link->priv;
157 link->state |= DEV_SUSPEND; 178 int i;
158
159 if (link->state & DEV_CONFIG) {
160 struct serial_info *info = link->priv;
161 int i;
162
163 for (i = 0; i < info->ndev; i++)
164 serial8250_suspend_port(info->line[i]);
165 179
166 if (!info->slave) 180 for (i = 0; i < info->ndev; i++)
167 pcmcia_release_configuration(link->handle); 181 serial8250_suspend_port(info->line[i]);
168 }
169 182
170 return 0; 183 return 0;
171} 184}
172 185
173static int serial_resume(struct pcmcia_device *dev) 186static int serial_resume(struct pcmcia_device *link)
174{ 187{
175 dev_link_t *link = dev_to_instance(dev); 188 if (pcmcia_dev_present(link)) {
176 link->state &= ~DEV_SUSPEND;
177
178 if (DEV_OK(link)) {
179 struct serial_info *info = link->priv; 189 struct serial_info *info = link->priv;
180 int i; 190 int i;
181 191
182 if (!info->slave)
183 pcmcia_request_configuration(link->handle, &link->conf);
184
185 for (i = 0; i < info->ndev; i++) 192 for (i = 0; i < info->ndev; i++)
186 serial8250_resume_port(info->line[i]); 193 serial8250_resume_port(info->line[i]);
194 wakeup_card(info);
187 } 195 }
188 196
189 return 0; 197 return 0;
@@ -197,10 +205,9 @@ static int serial_resume(struct pcmcia_device *dev)
197 205
198======================================================================*/ 206======================================================================*/
199 207
200static int serial_probe(struct pcmcia_device *p_dev) 208static int serial_probe(struct pcmcia_device *link)
201{ 209{
202 struct serial_info *info; 210 struct serial_info *info;
203 dev_link_t *link;
204 211
205 DEBUG(0, "serial_attach()\n"); 212 DEBUG(0, "serial_attach()\n");
206 213
@@ -209,7 +216,7 @@ static int serial_probe(struct pcmcia_device *p_dev)
209 if (!info) 216 if (!info)
210 return -ENOMEM; 217 return -ENOMEM;
211 memset(info, 0, sizeof (*info)); 218 memset(info, 0, sizeof (*info));
212 link = &info->link; 219 info->p_dev = link;
213 link->priv = info; 220 link->priv = info;
214 221
215 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; 222 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
@@ -223,12 +230,7 @@ static int serial_probe(struct pcmcia_device *p_dev)
223 } 230 }
224 link->conf.IntType = INT_MEMORY_AND_IO; 231 link->conf.IntType = INT_MEMORY_AND_IO;
225 232
226 link->handle = p_dev; 233 return serial_config(link);
227 p_dev->instance = link;
228 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
229 serial_config(link);
230
231 return 0;
232} 234}
233 235
234/*====================================================================== 236/*======================================================================
@@ -240,9 +242,8 @@ static int serial_probe(struct pcmcia_device *p_dev)
240 242
241======================================================================*/ 243======================================================================*/
242 244
243static void serial_detach(struct pcmcia_device *p_dev) 245static void serial_detach(struct pcmcia_device *link)
244{ 246{
245 dev_link_t *link = dev_to_instance(p_dev);
246 struct serial_info *info = link->priv; 247 struct serial_info *info = link->priv;
247 248
248 DEBUG(0, "serial_detach(0x%p)\n", link); 249 DEBUG(0, "serial_detach(0x%p)\n", link);
@@ -263,7 +264,7 @@ static void serial_detach(struct pcmcia_device *p_dev)
263 264
264/*====================================================================*/ 265/*====================================================================*/
265 266
266static int setup_serial(client_handle_t handle, struct serial_info * info, 267static int setup_serial(struct pcmcia_device *handle, struct serial_info * info,
267 kio_addr_t iobase, int irq) 268 kio_addr_t iobase, int irq)
268{ 269{
269 struct uart_port port; 270 struct uart_port port;
@@ -298,7 +299,7 @@ static int setup_serial(client_handle_t handle, struct serial_info * info,
298/*====================================================================*/ 299/*====================================================================*/
299 300
300static int 301static int
301first_tuple(client_handle_t handle, tuple_t * tuple, cisparse_t * parse) 302first_tuple(struct pcmcia_device *handle, tuple_t * tuple, cisparse_t * parse)
302{ 303{
303 int i; 304 int i;
304 i = pcmcia_get_first_tuple(handle, tuple); 305 i = pcmcia_get_first_tuple(handle, tuple);
@@ -311,7 +312,7 @@ first_tuple(client_handle_t handle, tuple_t * tuple, cisparse_t * parse)
311} 312}
312 313
313static int 314static int
314next_tuple(client_handle_t handle, tuple_t * tuple, cisparse_t * parse) 315next_tuple(struct pcmcia_device *handle, tuple_t * tuple, cisparse_t * parse)
315{ 316{
316 int i; 317 int i;
317 i = pcmcia_get_next_tuple(handle, tuple); 318 i = pcmcia_get_next_tuple(handle, tuple);
@@ -325,11 +326,10 @@ next_tuple(client_handle_t handle, tuple_t * tuple, cisparse_t * parse)
325 326
326/*====================================================================*/ 327/*====================================================================*/
327 328
328static int simple_config(dev_link_t *link) 329static int simple_config(struct pcmcia_device *link)
329{ 330{
330 static const kio_addr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 }; 331 static const kio_addr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
331 static const int size_table[2] = { 8, 16 }; 332 static const int size_table[2] = { 8, 16 };
332 client_handle_t handle = link->handle;
333 struct serial_info *info = link->priv; 333 struct serial_info *info = link->priv;
334 struct serial_cfg_mem *cfg_mem; 334 struct serial_cfg_mem *cfg_mem;
335 tuple_t *tuple; 335 tuple_t *tuple;
@@ -350,7 +350,7 @@ static int simple_config(dev_link_t *link)
350 buf = cfg_mem->buf; 350 buf = cfg_mem->buf;
351 351
352 /* If the card is already configured, look up the port and irq */ 352 /* If the card is already configured, look up the port and irq */
353 i = pcmcia_get_configuration_info(handle, &config); 353 i = pcmcia_get_configuration_info(link, &config);
354 if ((i == CS_SUCCESS) && (config.Attributes & CONF_VALID_CLIENT)) { 354 if ((i == CS_SUCCESS) && (config.Attributes & CONF_VALID_CLIENT)) {
355 kio_addr_t port = 0; 355 kio_addr_t port = 0;
356 if ((config.BasePort2 != 0) && (config.NumPorts2 == 8)) { 356 if ((config.BasePort2 != 0) && (config.NumPorts2 == 8)) {
@@ -363,10 +363,9 @@ static int simple_config(dev_link_t *link)
363 } 363 }
364 if (info->slave) { 364 if (info->slave) {
365 kfree(cfg_mem); 365 kfree(cfg_mem);
366 return setup_serial(handle, info, port, config.AssignedIRQ); 366 return setup_serial(link, info, port, config.AssignedIRQ);
367 } 367 }
368 } 368 }
369 link->conf.Vcc = config.Vcc;
370 369
371 /* First pass: look for a config entry that looks normal. */ 370 /* First pass: look for a config entry that looks normal. */
372 tuple->TupleData = (cisdata_t *) buf; 371 tuple->TupleData = (cisdata_t *) buf;
@@ -377,12 +376,12 @@ static int simple_config(dev_link_t *link)
377 /* Two tries: without IO aliases, then with aliases */ 376 /* Two tries: without IO aliases, then with aliases */
378 for (s = 0; s < 2; s++) { 377 for (s = 0; s < 2; s++) {
379 for (try = 0; try < 2; try++) { 378 for (try = 0; try < 2; try++) {
380 i = first_tuple(handle, tuple, parse); 379 i = first_tuple(link, tuple, parse);
381 while (i != CS_NO_MORE_ITEMS) { 380 while (i != CS_NO_MORE_ITEMS) {
382 if (i != CS_SUCCESS) 381 if (i != CS_SUCCESS)
383 goto next_entry; 382 goto next_entry;
384 if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM)) 383 if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
385 link->conf.Vpp1 = link->conf.Vpp2 = 384 link->conf.Vpp =
386 cf->vpp1.param[CISTPL_POWER_VNOM] / 10000; 385 cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
387 if ((cf->io.nwin > 0) && (cf->io.win[0].len == size_table[s]) && 386 if ((cf->io.nwin > 0) && (cf->io.win[0].len == size_table[s]) &&
388 (cf->io.win[0].base != 0)) { 387 (cf->io.win[0].base != 0)) {
@@ -390,19 +389,19 @@ static int simple_config(dev_link_t *link)
390 link->io.BasePort1 = cf->io.win[0].base; 389 link->io.BasePort1 = cf->io.win[0].base;
391 link->io.IOAddrLines = (try == 0) ? 390 link->io.IOAddrLines = (try == 0) ?
392 16 : cf->io.flags & CISTPL_IO_LINES_MASK; 391 16 : cf->io.flags & CISTPL_IO_LINES_MASK;
393 i = pcmcia_request_io(link->handle, &link->io); 392 i = pcmcia_request_io(link, &link->io);
394 if (i == CS_SUCCESS) 393 if (i == CS_SUCCESS)
395 goto found_port; 394 goto found_port;
396 } 395 }
397next_entry: 396next_entry:
398 i = next_tuple(handle, tuple, parse); 397 i = next_tuple(link, tuple, parse);
399 } 398 }
400 } 399 }
401 } 400 }
402 /* Second pass: try to find an entry that isn't picky about 401 /* Second pass: try to find an entry that isn't picky about
403 its base address, then try to grab any standard serial port 402 its base address, then try to grab any standard serial port
404 address, and finally try to get any free port. */ 403 address, and finally try to get any free port. */
405 i = first_tuple(handle, tuple, parse); 404 i = first_tuple(link, tuple, parse);
406 while (i != CS_NO_MORE_ITEMS) { 405 while (i != CS_NO_MORE_ITEMS) {
407 if ((i == CS_SUCCESS) && (cf->io.nwin > 0) && 406 if ((i == CS_SUCCESS) && (cf->io.nwin > 0) &&
408 ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) { 407 ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
@@ -410,50 +409,48 @@ next_entry:
410 for (j = 0; j < 5; j++) { 409 for (j = 0; j < 5; j++) {
411 link->io.BasePort1 = base[j]; 410 link->io.BasePort1 = base[j];
412 link->io.IOAddrLines = base[j] ? 16 : 3; 411 link->io.IOAddrLines = base[j] ? 16 : 3;
413 i = pcmcia_request_io(link->handle, &link->io); 412 i = pcmcia_request_io(link, &link->io);
414 if (i == CS_SUCCESS) 413 if (i == CS_SUCCESS)
415 goto found_port; 414 goto found_port;
416 } 415 }
417 } 416 }
418 i = next_tuple(handle, tuple, parse); 417 i = next_tuple(link, tuple, parse);
419 } 418 }
420 419
421 found_port: 420 found_port:
422 if (i != CS_SUCCESS) { 421 if (i != CS_SUCCESS) {
423 printk(KERN_NOTICE 422 printk(KERN_NOTICE
424 "serial_cs: no usable port range found, giving up\n"); 423 "serial_cs: no usable port range found, giving up\n");
425 cs_error(link->handle, RequestIO, i); 424 cs_error(link, RequestIO, i);
426 kfree(cfg_mem); 425 kfree(cfg_mem);
427 return -1; 426 return -1;
428 } 427 }
429 428
430 i = pcmcia_request_irq(link->handle, &link->irq); 429 i = pcmcia_request_irq(link, &link->irq);
431 if (i != CS_SUCCESS) { 430 if (i != CS_SUCCESS) {
432 cs_error(link->handle, RequestIRQ, i); 431 cs_error(link, RequestIRQ, i);
433 link->irq.AssignedIRQ = 0; 432 link->irq.AssignedIRQ = 0;
434 } 433 }
435 if (info->multi && (info->manfid == MANFID_3COM)) 434 if (info->multi && (info->manfid == MANFID_3COM))
436 link->conf.ConfigIndex &= ~(0x08); 435 link->conf.ConfigIndex &= ~(0x08);
437 i = pcmcia_request_configuration(link->handle, &link->conf); 436 i = pcmcia_request_configuration(link, &link->conf);
438 if (i != CS_SUCCESS) { 437 if (i != CS_SUCCESS) {
439 cs_error(link->handle, RequestConfiguration, i); 438 cs_error(link, RequestConfiguration, i);
440 kfree(cfg_mem); 439 kfree(cfg_mem);
441 return -1; 440 return -1;
442 } 441 }
443 kfree(cfg_mem); 442 kfree(cfg_mem);
444 return setup_serial(handle, info, link->io.BasePort1, link->irq.AssignedIRQ); 443 return setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ);
445} 444}
446 445
447static int multi_config(dev_link_t * link) 446static int multi_config(struct pcmcia_device * link)
448{ 447{
449 client_handle_t handle = link->handle;
450 struct serial_info *info = link->priv; 448 struct serial_info *info = link->priv;
451 struct serial_cfg_mem *cfg_mem; 449 struct serial_cfg_mem *cfg_mem;
452 tuple_t *tuple; 450 tuple_t *tuple;
453 u_char *buf; 451 u_char *buf;
454 cisparse_t *parse; 452 cisparse_t *parse;
455 cistpl_cftable_entry_t *cf; 453 cistpl_cftable_entry_t *cf;
456 config_info_t config;
457 int i, rc, base2 = 0; 454 int i, rc, base2 = 0;
458 455
459 cfg_mem = kmalloc(sizeof(struct serial_cfg_mem), GFP_KERNEL); 456 cfg_mem = kmalloc(sizeof(struct serial_cfg_mem), GFP_KERNEL);
@@ -464,14 +461,6 @@ static int multi_config(dev_link_t * link)
464 cf = &parse->cftable_entry; 461 cf = &parse->cftable_entry;
465 buf = cfg_mem->buf; 462 buf = cfg_mem->buf;
466 463
467 i = pcmcia_get_configuration_info(handle, &config);
468 if (i != CS_SUCCESS) {
469 cs_error(handle, GetConfigurationInfo, i);
470 rc = -1;
471 goto free_cfg_mem;
472 }
473 link->conf.Vcc = config.Vcc;
474
475 tuple->TupleData = (cisdata_t *) buf; 464 tuple->TupleData = (cisdata_t *) buf;
476 tuple->TupleOffset = 0; 465 tuple->TupleOffset = 0;
477 tuple->TupleDataMax = 255; 466 tuple->TupleDataMax = 255;
@@ -480,7 +469,7 @@ static int multi_config(dev_link_t * link)
480 469
481 /* First, look for a generic full-sized window */ 470 /* First, look for a generic full-sized window */
482 link->io.NumPorts1 = info->multi * 8; 471 link->io.NumPorts1 = info->multi * 8;
483 i = first_tuple(handle, tuple, parse); 472 i = first_tuple(link, tuple, parse);
484 while (i != CS_NO_MORE_ITEMS) { 473 while (i != CS_NO_MORE_ITEMS) {
485 /* The quad port cards have bad CIS's, so just look for a 474 /* The quad port cards have bad CIS's, so just look for a
486 window larger than 8 ports and assume it will be right */ 475 window larger than 8 ports and assume it will be right */
@@ -490,19 +479,19 @@ static int multi_config(dev_link_t * link)
490 link->io.BasePort1 = cf->io.win[0].base; 479 link->io.BasePort1 = cf->io.win[0].base;
491 link->io.IOAddrLines = 480 link->io.IOAddrLines =
492 cf->io.flags & CISTPL_IO_LINES_MASK; 481 cf->io.flags & CISTPL_IO_LINES_MASK;
493 i = pcmcia_request_io(link->handle, &link->io); 482 i = pcmcia_request_io(link, &link->io);
494 base2 = link->io.BasePort1 + 8; 483 base2 = link->io.BasePort1 + 8;
495 if (i == CS_SUCCESS) 484 if (i == CS_SUCCESS)
496 break; 485 break;
497 } 486 }
498 i = next_tuple(handle, tuple, parse); 487 i = next_tuple(link, tuple, parse);
499 } 488 }
500 489
501 /* If that didn't work, look for two windows */ 490 /* If that didn't work, look for two windows */
502 if (i != CS_SUCCESS) { 491 if (i != CS_SUCCESS) {
503 link->io.NumPorts1 = link->io.NumPorts2 = 8; 492 link->io.NumPorts1 = link->io.NumPorts2 = 8;
504 info->multi = 2; 493 info->multi = 2;
505 i = first_tuple(handle, tuple, parse); 494 i = first_tuple(link, tuple, parse);
506 while (i != CS_NO_MORE_ITEMS) { 495 while (i != CS_NO_MORE_ITEMS) {
507 if ((i == CS_SUCCESS) && (cf->io.nwin == 2)) { 496 if ((i == CS_SUCCESS) && (cf->io.nwin == 2)) {
508 link->conf.ConfigIndex = cf->index; 497 link->conf.ConfigIndex = cf->index;
@@ -510,26 +499,26 @@ static int multi_config(dev_link_t * link)
510 link->io.BasePort2 = cf->io.win[1].base; 499 link->io.BasePort2 = cf->io.win[1].base;
511 link->io.IOAddrLines = 500 link->io.IOAddrLines =
512 cf->io.flags & CISTPL_IO_LINES_MASK; 501 cf->io.flags & CISTPL_IO_LINES_MASK;
513 i = pcmcia_request_io(link->handle, &link->io); 502 i = pcmcia_request_io(link, &link->io);
514 base2 = link->io.BasePort2; 503 base2 = link->io.BasePort2;
515 if (i == CS_SUCCESS) 504 if (i == CS_SUCCESS)
516 break; 505 break;
517 } 506 }
518 i = next_tuple(handle, tuple, parse); 507 i = next_tuple(link, tuple, parse);
519 } 508 }
520 } 509 }
521 510
522 if (i != CS_SUCCESS) { 511 if (i != CS_SUCCESS) {
523 cs_error(link->handle, RequestIO, i); 512 cs_error(link, RequestIO, i);
524 rc = -1; 513 rc = -1;
525 goto free_cfg_mem; 514 goto free_cfg_mem;
526 } 515 }
527 516
528 i = pcmcia_request_irq(link->handle, &link->irq); 517 i = pcmcia_request_irq(link, &link->irq);
529 if (i != CS_SUCCESS) { 518 if (i != CS_SUCCESS) {
530 printk(KERN_NOTICE 519 printk(KERN_NOTICE
531 "serial_cs: no usable port range found, giving up\n"); 520 "serial_cs: no usable port range found, giving up\n");
532 cs_error(link->handle, RequestIRQ, i); 521 cs_error(link, RequestIRQ, i);
533 link->irq.AssignedIRQ = 0; 522 link->irq.AssignedIRQ = 0;
534 } 523 }
535 /* Socket Dual IO: this enables irq's for second port */ 524 /* Socket Dual IO: this enables irq's for second port */
@@ -537,35 +526,43 @@ static int multi_config(dev_link_t * link)
537 link->conf.Present |= PRESENT_EXT_STATUS; 526 link->conf.Present |= PRESENT_EXT_STATUS;
538 link->conf.ExtStatus = ESR_REQ_ATTN_ENA; 527 link->conf.ExtStatus = ESR_REQ_ATTN_ENA;
539 } 528 }
540 i = pcmcia_request_configuration(link->handle, &link->conf); 529 i = pcmcia_request_configuration(link, &link->conf);
541 if (i != CS_SUCCESS) { 530 if (i != CS_SUCCESS) {
542 cs_error(link->handle, RequestConfiguration, i); 531 cs_error(link, RequestConfiguration, i);
543 rc = -1; 532 rc = -1;
544 goto free_cfg_mem; 533 goto free_cfg_mem;
545 } 534 }
546 535
547 /* The Oxford Semiconductor OXCF950 cards are in fact single-port: 536 /* The Oxford Semiconductor OXCF950 cards are in fact single-port:
548 8 registers are for the UART, the others are extra registers */ 537 * 8 registers are for the UART, the others are extra registers.
549 if (info->manfid == MANFID_OXSEMI) { 538 * Siemen's MC45 PCMCIA (Possio's GCC) is OXCF950 based too.
539 */
540 if (info->manfid == MANFID_OXSEMI || (info->manfid == MANFID_POSSIO &&
541 info->prodid == PRODID_POSSIO_GCC)) {
542 int err;
543
550 if (cf->index == 1 || cf->index == 3) { 544 if (cf->index == 1 || cf->index == 3) {
551 setup_serial(handle, info, base2, link->irq.AssignedIRQ); 545 err = setup_serial(link, info, base2,
552 outb(12, link->io.BasePort1 + 1); 546 link->irq.AssignedIRQ);
547 base2 = link->io.BasePort1;
553 } else { 548 } else {
554 setup_serial(handle, info, link->io.BasePort1, link->irq.AssignedIRQ); 549 err = setup_serial(link, info, link->io.BasePort1,
555 outb(12, base2 + 1); 550 link->irq.AssignedIRQ);
556 } 551 }
552 info->c950ctrl = base2;
553 wakeup_card(info);
557 rc = 0; 554 rc = 0;
558 goto free_cfg_mem; 555 goto free_cfg_mem;
559 } 556 }
560 557
561 setup_serial(handle, info, link->io.BasePort1, link->irq.AssignedIRQ); 558 setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ);
562 /* The Nokia cards are not really multiport cards */ 559 /* The Nokia cards are not really multiport cards */
563 if (info->manfid == MANFID_NOKIA) { 560 if (info->manfid == MANFID_NOKIA) {
564 rc = 0; 561 rc = 0;
565 goto free_cfg_mem; 562 goto free_cfg_mem;
566 } 563 }
567 for (i = 0; i < info->multi - 1; i++) 564 for (i = 0; i < info->multi - 1; i++)
568 setup_serial(handle, info, base2 + (8 * i), 565 setup_serial(link, info, base2 + (8 * i),
569 link->irq.AssignedIRQ); 566 link->irq.AssignedIRQ);
570 rc = 0; 567 rc = 0;
571free_cfg_mem: 568free_cfg_mem:
@@ -581,9 +578,8 @@ free_cfg_mem:
581 578
582======================================================================*/ 579======================================================================*/
583 580
584void serial_config(dev_link_t * link) 581static int serial_config(struct pcmcia_device * link)
585{ 582{
586 client_handle_t handle = link->handle;
587 struct serial_info *info = link->priv; 583 struct serial_info *info = link->priv;
588 struct serial_cfg_mem *cfg_mem; 584 struct serial_cfg_mem *cfg_mem;
589 tuple_t *tuple; 585 tuple_t *tuple;
@@ -609,7 +605,7 @@ void serial_config(dev_link_t * link)
609 tuple->Attributes = 0; 605 tuple->Attributes = 0;
610 /* Get configuration register information */ 606 /* Get configuration register information */
611 tuple->DesiredTuple = CISTPL_CONFIG; 607 tuple->DesiredTuple = CISTPL_CONFIG;
612 last_ret = first_tuple(handle, tuple, parse); 608 last_ret = first_tuple(link, tuple, parse);
613 if (last_ret != CS_SUCCESS) { 609 if (last_ret != CS_SUCCESS) {
614 last_fn = ParseTuple; 610 last_fn = ParseTuple;
615 goto cs_failed; 611 goto cs_failed;
@@ -617,18 +613,16 @@ void serial_config(dev_link_t * link)
617 link->conf.ConfigBase = parse->config.base; 613 link->conf.ConfigBase = parse->config.base;
618 link->conf.Present = parse->config.rmask[0]; 614 link->conf.Present = parse->config.rmask[0];
619 615
620 /* Configure card */
621 link->state |= DEV_CONFIG;
622
623 /* Is this a compliant multifunction card? */ 616 /* Is this a compliant multifunction card? */
624 tuple->DesiredTuple = CISTPL_LONGLINK_MFC; 617 tuple->DesiredTuple = CISTPL_LONGLINK_MFC;
625 tuple->Attributes = TUPLE_RETURN_COMMON | TUPLE_RETURN_LINK; 618 tuple->Attributes = TUPLE_RETURN_COMMON | TUPLE_RETURN_LINK;
626 info->multi = (first_tuple(handle, tuple, parse) == CS_SUCCESS); 619 info->multi = (first_tuple(link, tuple, parse) == CS_SUCCESS);
627 620
628 /* Is this a multiport card? */ 621 /* Is this a multiport card? */
629 tuple->DesiredTuple = CISTPL_MANFID; 622 tuple->DesiredTuple = CISTPL_MANFID;
630 if (first_tuple(handle, tuple, parse) == CS_SUCCESS) { 623 if (first_tuple(link, tuple, parse) == CS_SUCCESS) {
631 info->manfid = parse->manfid.manf; 624 info->manfid = parse->manfid.manf;
625 info->prodid = le16_to_cpu(buf[1]);
632 for (i = 0; i < MULTI_COUNT; i++) 626 for (i = 0; i < MULTI_COUNT; i++)
633 if ((info->manfid == multi_id[i].manfid) && 627 if ((info->manfid == multi_id[i].manfid) &&
634 (parse->manfid.card == multi_id[i].prodid)) 628 (parse->manfid.card == multi_id[i].prodid))
@@ -641,11 +635,11 @@ void serial_config(dev_link_t * link)
641 multifunction cards that ask for appropriate IO port ranges */ 635 multifunction cards that ask for appropriate IO port ranges */
642 tuple->DesiredTuple = CISTPL_FUNCID; 636 tuple->DesiredTuple = CISTPL_FUNCID;
643 if ((info->multi == 0) && 637 if ((info->multi == 0) &&
644 ((first_tuple(handle, tuple, parse) != CS_SUCCESS) || 638 ((first_tuple(link, tuple, parse) != CS_SUCCESS) ||
645 (parse->funcid.func == CISTPL_FUNCID_MULTI) || 639 (parse->funcid.func == CISTPL_FUNCID_MULTI) ||
646 (parse->funcid.func == CISTPL_FUNCID_SERIAL))) { 640 (parse->funcid.func == CISTPL_FUNCID_SERIAL))) {
647 tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; 641 tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY;
648 if (first_tuple(handle, tuple, parse) == CS_SUCCESS) { 642 if (first_tuple(link, tuple, parse) == CS_SUCCESS) {
649 if ((cf->io.nwin == 1) && (cf->io.win[0].len % 8 == 0)) 643 if ((cf->io.nwin == 1) && (cf->io.win[0].len % 8 == 0))
650 info->multi = cf->io.win[0].len >> 3; 644 info->multi = cf->io.win[0].len >> 3;
651 if ((cf->io.nwin == 2) && (cf->io.win[0].len == 8) && 645 if ((cf->io.nwin == 2) && (cf->io.win[0].len == 8) &&
@@ -664,31 +658,30 @@ void serial_config(dev_link_t * link)
664 658
665 if (info->manfid == MANFID_IBM) { 659 if (info->manfid == MANFID_IBM) {
666 conf_reg_t reg = { 0, CS_READ, 0x800, 0 }; 660 conf_reg_t reg = { 0, CS_READ, 0x800, 0 };
667 last_ret = pcmcia_access_configuration_register(link->handle, &reg); 661 last_ret = pcmcia_access_configuration_register(link, &reg);
668 if (last_ret) { 662 if (last_ret) {
669 last_fn = AccessConfigurationRegister; 663 last_fn = AccessConfigurationRegister;
670 goto cs_failed; 664 goto cs_failed;
671 } 665 }
672 reg.Action = CS_WRITE; 666 reg.Action = CS_WRITE;
673 reg.Value = reg.Value | 1; 667 reg.Value = reg.Value | 1;
674 last_ret = pcmcia_access_configuration_register(link->handle, &reg); 668 last_ret = pcmcia_access_configuration_register(link, &reg);
675 if (last_ret) { 669 if (last_ret) {
676 last_fn = AccessConfigurationRegister; 670 last_fn = AccessConfigurationRegister;
677 goto cs_failed; 671 goto cs_failed;
678 } 672 }
679 } 673 }
680 674
681 link->dev = &info->node[0]; 675 link->dev_node = &info->node[0];
682 link->state &= ~DEV_CONFIG_PENDING;
683 kfree(cfg_mem); 676 kfree(cfg_mem);
684 return; 677 return 0;
685 678
686 cs_failed: 679 cs_failed:
687 cs_error(link->handle, last_fn, last_ret); 680 cs_error(link, last_fn, last_ret);
688 failed: 681 failed:
689 serial_remove(link); 682 serial_remove(link);
690 link->state &= ~DEV_CONFIG_PENDING;
691 kfree(cfg_mem); 683 kfree(cfg_mem);
684 return -ENODEV;
692} 685}
693 686
694static struct pcmcia_device_id serial_ids[] = { 687static struct pcmcia_device_id serial_ids[] = {
@@ -739,6 +732,7 @@ static struct pcmcia_device_id serial_ids[] = {
739 PCMCIA_MFC_DEVICE_PROD_ID1(1, "Motorola MARQUIS", 0xf03e4e77), 732 PCMCIA_MFC_DEVICE_PROD_ID1(1, "Motorola MARQUIS", 0xf03e4e77),
740 PCMCIA_MFC_DEVICE_PROD_ID2(1, "FAX/Modem/Ethernet Combo Card ", 0x1ed59302), 733 PCMCIA_MFC_DEVICE_PROD_ID2(1, "FAX/Modem/Ethernet Combo Card ", 0x1ed59302),
741 PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0301), 734 PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0301),
735 PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x0276),
742 PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0039), 736 PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0039),
743 PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0006), 737 PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0006),
744 PCMCIA_DEVICE_MANF_CARD(0x0105, 0x410a), 738 PCMCIA_DEVICE_MANF_CARD(0x0105, 0x410a),
@@ -757,6 +751,7 @@ static struct pcmcia_device_id serial_ids[] = {
757 PCMCIA_DEVICE_PROD_ID14("MEGAHERTZ", "PCMCIA MODEM", 0xf510db04, 0xbd6c43ef), 751 PCMCIA_DEVICE_PROD_ID14("MEGAHERTZ", "PCMCIA MODEM", 0xf510db04, 0xbd6c43ef),
758 PCMCIA_DEVICE_PROD_ID124("TOSHIBA", "T144PF", "PCMCIA MODEM", 0xb4585a1a, 0x7271409c, 0xbd6c43ef), 752 PCMCIA_DEVICE_PROD_ID124("TOSHIBA", "T144PF", "PCMCIA MODEM", 0xb4585a1a, 0x7271409c, 0xbd6c43ef),
759 PCMCIA_DEVICE_PROD_ID123("FUJITSU", "FC14F ", "MBH10213", 0x6ee5a3d8, 0x30ead12b, 0xb00f05a0), 753 PCMCIA_DEVICE_PROD_ID123("FUJITSU", "FC14F ", "MBH10213", 0x6ee5a3d8, 0x30ead12b, 0xb00f05a0),
754 PCMCIA_DEVICE_PROD_ID123("Novatel Wireless", "Merlin UMTS Modem", "U630", 0x32607776, 0xd9e73b13, 0xe87332e),
760 PCMCIA_DEVICE_PROD_ID13("MEGAHERTZ", "V.34 PCMCIA MODEM", 0xf510db04, 0xbb2cce4a), 755 PCMCIA_DEVICE_PROD_ID13("MEGAHERTZ", "V.34 PCMCIA MODEM", 0xf510db04, 0xbb2cce4a),
761 PCMCIA_DEVICE_PROD_ID12("Brain Boxes", "Bluetooth PC Card", 0xee138382, 0xd4ce9b02), 756 PCMCIA_DEVICE_PROD_ID12("Brain Boxes", "Bluetooth PC Card", 0xee138382, 0xd4ce9b02),
762 PCMCIA_DEVICE_PROD_ID12("CIRRUS LOGIC", "FAX MODEM", 0xe625f451, 0xcecd6dfa), 757 PCMCIA_DEVICE_PROD_ID12("CIRRUS LOGIC", "FAX MODEM", 0xe625f451, 0xcecd6dfa),