[PATCH] pcmcia: new suspend core

Move the suspend and resume methods out of the event handler, and into
special functions. Also use these functions for pre- and post-reset, as
almost all drivers already do, and the remaining ones can easily be
converted.

Bugfix to include/pcmcia/ds.c
Signed-off-by: Andrew Morton <akpm@osdl.org>

Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
This commit is contained in:
Dominik Brodowski 2005-11-14 21:21:18 +01:00
parent 63e7ebd064
commit 98e4c28b7e
45 changed files with 1434 additions and 994 deletions

View File

@ -1,5 +1,11 @@
This file details changes in 2.6 which affect PCMCIA card driver authors: This file details changes in 2.6 which affect PCMCIA card driver authors:
* Move suspend, resume and reset out of event handler (as of 2.6.16)
int (*suspend) (struct pcmcia_device *dev);
int (*resume) (struct pcmcia_device *dev);
should be initialized in struct pcmcia_driver, and handle
(SUSPEND == RESET_PHYSICAL) and (RESUME == CARD_RESET) events
* event handler initialization in struct pcmcia_driver (as of 2.6.13) * event handler initialization in struct pcmcia_driver (as of 2.6.13)
The event handler is notified of all events, and must be initialized The event handler is notified of all events, and must be initialized
as the event() callback in the driver's struct pcmcia_driver. as the event() callback in the driver's struct pcmcia_driver.

View File

@ -1045,6 +1045,27 @@ static void bluecard_release(dev_link_t *link)
link->state &= ~DEV_CONFIG; link->state &= ~DEV_CONFIG;
} }
static int bluecard_suspend(struct pcmcia_device *dev)
{
dev_link_t *link = dev_to_instance(dev);
link->state |= DEV_SUSPEND;
if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle);
return 0;
}
static int bluecard_resume(struct pcmcia_device *dev)
{
dev_link_t *link = dev_to_instance(dev);
link->state &= ~DEV_SUSPEND;
if (DEV_OK(link))
pcmcia_request_configuration(link->handle, &link->conf);
return 0;
}
static int bluecard_event(event_t event, int priority, event_callback_args_t *args) static int bluecard_event(event_t event, int priority, event_callback_args_t *args)
{ {
@ -1063,20 +1084,6 @@ static int bluecard_event(event_t event, int priority, event_callback_args_t *ar
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
bluecard_config(link); bluecard_config(link);
break; break;
case CS_EVENT_PM_SUSPEND:
link->state |= DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_RESET_PHYSICAL:
if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle);
break;
case CS_EVENT_PM_RESUME:
link->state &= ~DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_CARD_RESET:
if (DEV_OK(link))
pcmcia_request_configuration(link->handle, &link->conf);
break;
} }
return 0; return 0;
@ -1099,6 +1106,8 @@ static struct pcmcia_driver bluecard_driver = {
.event = bluecard_event, .event = bluecard_event,
.detach = bluecard_detach, .detach = bluecard_detach,
.id_table = bluecard_ids, .id_table = bluecard_ids,
.suspend = bluecard_suspend,
.resume = bluecard_resume,
}; };
static int __init init_bluecard_cs(void) static int __init init_bluecard_cs(void)

View File

@ -891,6 +891,27 @@ static void bt3c_release(dev_link_t *link)
link->state &= ~DEV_CONFIG; link->state &= ~DEV_CONFIG;
} }
static int bt3c_suspend(struct pcmcia_device *dev)
{
dev_link_t *link = dev_to_instance(dev);
link->state |= DEV_SUSPEND;
if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle);
return 0;
}
static int bt3c_resume(struct pcmcia_device *dev)
{
dev_link_t *link = dev_to_instance(dev);
link->state &= ~DEV_SUSPEND;
if (DEV_OK(link))
pcmcia_request_configuration(link->handle, &link->conf);
return 0;
}
static int bt3c_event(event_t event, int priority, event_callback_args_t *args) static int bt3c_event(event_t event, int priority, event_callback_args_t *args)
{ {
@ -909,20 +930,6 @@ static int bt3c_event(event_t event, int priority, event_callback_args_t *args)
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
bt3c_config(link); bt3c_config(link);
break; break;
case CS_EVENT_PM_SUSPEND:
link->state |= DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_RESET_PHYSICAL:
if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle);
break;
case CS_EVENT_PM_RESUME:
link->state &= ~DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_CARD_RESET:
if (DEV_OK(link))
pcmcia_request_configuration(link->handle, &link->conf);
break;
} }
return 0; return 0;
@ -943,6 +950,8 @@ static struct pcmcia_driver bt3c_driver = {
.event = bt3c_event, .event = bt3c_event,
.detach = bt3c_detach, .detach = bt3c_detach,
.id_table = bt3c_ids, .id_table = bt3c_ids,
.suspend = bt3c_suspend,
.resume = bt3c_resume,
}; };
static int __init init_bt3c_cs(void) static int __init init_bt3c_cs(void)

View File

@ -811,6 +811,28 @@ static void btuart_release(dev_link_t *link)
link->state &= ~DEV_CONFIG; link->state &= ~DEV_CONFIG;
} }
static int btuart_suspend(struct pcmcia_device *dev)
{
dev_link_t *link = dev_to_instance(dev);
link->state |= DEV_SUSPEND;
if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle);
return 0;
}
static int btuart_resume(struct pcmcia_device *dev)
{
dev_link_t *link = dev_to_instance(dev);
link->state &= ~DEV_SUSPEND;
if (DEV_OK(link))
pcmcia_request_configuration(link->handle, &link->conf);
return 0;
}
static int btuart_event(event_t event, int priority, event_callback_args_t *args) static int btuart_event(event_t event, int priority, event_callback_args_t *args)
{ {
@ -829,20 +851,6 @@ static int btuart_event(event_t event, int priority, event_callback_args_t *args
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
btuart_config(link); btuart_config(link);
break; break;
case CS_EVENT_PM_SUSPEND:
link->state |= DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_RESET_PHYSICAL:
if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle);
break;
case CS_EVENT_PM_RESUME:
link->state &= ~DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_CARD_RESET:
if (DEV_OK(link))
pcmcia_request_configuration(link->handle, &link->conf);
break;
} }
return 0; return 0;
@ -863,6 +871,8 @@ static struct pcmcia_driver btuart_driver = {
.event = btuart_event, .event = btuart_event,
.detach = btuart_detach, .detach = btuart_detach,
.id_table = btuart_ids, .id_table = btuart_ids,
.suspend = btuart_suspend,
.resume = btuart_resume,
}; };
static int __init init_btuart_cs(void) static int __init init_btuart_cs(void)

View File

@ -763,6 +763,27 @@ static void dtl1_release(dev_link_t *link)
link->state &= ~DEV_CONFIG; link->state &= ~DEV_CONFIG;
} }
static int dtl1_suspend(struct pcmcia_device *dev)
{
dev_link_t *link = dev_to_instance(dev);
link->state |= DEV_SUSPEND;
if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle);
return 0;
}
static int dtl1_resume(struct pcmcia_device *dev)
{
dev_link_t *link = dev_to_instance(dev);
link->state &= ~DEV_SUSPEND;
if (DEV_OK(link))
pcmcia_request_configuration(link->handle, &link->conf);
return 0;
}
static int dtl1_event(event_t event, int priority, event_callback_args_t *args) static int dtl1_event(event_t event, int priority, event_callback_args_t *args)
{ {
@ -781,20 +802,6 @@ static int dtl1_event(event_t event, int priority, event_callback_args_t *args)
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
dtl1_config(link); dtl1_config(link);
break; break;
case CS_EVENT_PM_SUSPEND:
link->state |= DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_RESET_PHYSICAL:
if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle);
break;
case CS_EVENT_PM_RESUME:
link->state &= ~DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_CARD_RESET:
if (DEV_OK(link))
pcmcia_request_configuration(link->handle, &link->conf);
break;
} }
return 0; return 0;
@ -816,6 +823,8 @@ static struct pcmcia_driver dtl1_driver = {
.event = dtl1_event, .event = dtl1_event,
.detach = dtl1_detach, .detach = dtl1_detach,
.id_table = dtl1_ids, .id_table = dtl1_ids,
.suspend = dtl1_suspend,
.resume = dtl1_resume,
}; };
static int __init init_dtl1_cs(void) static int __init init_dtl1_cs(void)

View File

@ -1893,33 +1893,6 @@ static int cm4000_event(event_t event, int priority,
link->state &= ~DEV_PRESENT; link->state &= ~DEV_PRESENT;
stop_monitor(dev); stop_monitor(dev);
break; break;
case CS_EVENT_PM_SUSPEND:
DEBUGP(5, dev, "CS_EVENT_PM_SUSPEND "
"(fall-through to CS_EVENT_RESET_PHYSICAL)\n");
link->state |= DEV_SUSPEND;
/* fall-through */
case CS_EVENT_RESET_PHYSICAL:
DEBUGP(5, dev, "CS_EVENT_RESET_PHYSICAL\n");
if (link->state & DEV_CONFIG) {
DEBUGP(5, dev, "ReleaseConfiguration\n");
pcmcia_release_configuration(link->handle);
}
stop_monitor(dev);
break;
case CS_EVENT_PM_RESUME:
DEBUGP(5, dev, "CS_EVENT_PM_RESUME "
"(fall-through to CS_EVENT_CARD_RESET)\n");
link->state &= ~DEV_SUSPEND;
/* fall-through */
case CS_EVENT_CARD_RESET:
DEBUGP(5, dev, "CS_EVENT_CARD_RESET\n");
if ((link->state & DEV_CONFIG)) {
DEBUGP(5, dev, "RequestConfiguration\n");
pcmcia_request_configuration(link->handle, &link->conf);
}
if (link->open)
start_monitor(dev);
break;
default: default:
DEBUGP(5, dev, "unknown event %.2x\n", event); DEBUGP(5, dev, "unknown event %.2x\n", event);
break; break;
@ -1928,6 +1901,38 @@ static int cm4000_event(event_t event, int priority,
return CS_SUCCESS; return CS_SUCCESS;
} }
static int cm4000_suspend(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
struct cm4000_dev *dev;
dev = link->priv;
link->state |= DEV_SUSPEND;
if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle);
stop_monitor(dev);
return 0;
}
static int cm4000_resume(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
struct cm4000_dev *dev;
dev = link->priv;
link->state &= ~DEV_SUSPEND;
if (link->state & DEV_CONFIG)
pcmcia_request_configuration(link->handle, &link->conf);
if (link->open)
start_monitor(dev);
return 0;
}
static void cm4000_release(dev_link_t *link) static void cm4000_release(dev_link_t *link)
{ {
cmm_cm4000_release(link->priv); /* delay release until device closed */ cmm_cm4000_release(link->priv); /* delay release until device closed */
@ -2044,6 +2049,8 @@ static struct pcmcia_driver cm4000_driver = {
}, },
.attach = cm4000_attach, .attach = cm4000_attach,
.detach = cm4000_detach, .detach = cm4000_detach,
.suspend = cm4000_suspend,
.resume = cm4000_resume,
.event = cm4000_event, .event = cm4000_event,
.id_table = cm4000_ids, .id_table = cm4000_ids,
}; };

View File

@ -656,31 +656,7 @@ static int reader_event(event_t event, int priority,
DEBUGP(5, dev, "CS_EVENT_CARD_REMOVAL\n"); DEBUGP(5, dev, "CS_EVENT_CARD_REMOVAL\n");
link->state &= ~DEV_PRESENT; link->state &= ~DEV_PRESENT;
break; break;
case CS_EVENT_PM_SUSPEND:
DEBUGP(5, dev, "CS_EVENT_PM_SUSPEND "
"(fall-through to CS_EVENT_RESET_PHYSICAL)\n");
link->state |= DEV_SUSPEND;
case CS_EVENT_RESET_PHYSICAL:
DEBUGP(5, dev, "CS_EVENT_RESET_PHYSICAL\n");
if (link->state & DEV_CONFIG) {
DEBUGP(5, dev, "ReleaseConfiguration\n");
pcmcia_release_configuration(link->handle);
}
break;
case CS_EVENT_PM_RESUME:
DEBUGP(5, dev, "CS_EVENT_PM_RESUME "
"(fall-through to CS_EVENT_CARD_RESET)\n");
link->state &= ~DEV_SUSPEND;
case CS_EVENT_CARD_RESET:
DEBUGP(5, dev, "CS_EVENT_CARD_RESET\n");
if ((link->state & DEV_CONFIG)) {
DEBUGP(5, dev, "RequestConfiguration\n");
pcmcia_request_configuration(link->handle,
&link->conf);
}
break;
default: default:
DEBUGP(5, dev, "reader_event: unknown event %.2x\n", DEBUGP(5, dev, "reader_event: unknown event %.2x\n",
event); event);
@ -690,6 +666,28 @@ static int reader_event(event_t event, int priority,
return CS_SUCCESS; return CS_SUCCESS;
} }
static int reader_suspend(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
link->state |= DEV_SUSPEND;
if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle);
return 0;
}
static int reader_resume(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
link->state &= ~DEV_SUSPEND;
if (link->state & DEV_CONFIG)
pcmcia_request_configuration(link->handle, &link->conf);
return 0;
}
static void reader_release(dev_link_t *link) static void reader_release(dev_link_t *link)
{ {
cm4040_reader_release(link->priv); cm4040_reader_release(link->priv);
@ -806,6 +804,8 @@ static struct pcmcia_driver reader_driver = {
}, },
.attach = reader_attach, .attach = reader_attach,
.detach = reader_detach, .detach = reader_detach,
.suspend = reader_suspend,
.resume = reader_resume,
.event = reader_event, .event = reader_event,
.id_table = cm4040_ids, .id_table = cm4040_ids,
}; };

View File

@ -773,11 +773,37 @@ static void mgslpc_detach(dev_link_t *link)
mgslpc_remove_device((MGSLPC_INFO *)link->priv); mgslpc_remove_device((MGSLPC_INFO *)link->priv);
} }
static int mgslpc_suspend(struct pcmcia_device *dev)
{
dev_link_t *link = dev_to_instance(dev);
MGSLPC_INFO *info = link->priv;
link->state |= DEV_SUSPEND;
info->stop = 1;
if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle);
return 0;
}
static int mgslpc_resume(struct pcmcia_device *dev)
{
dev_link_t *link = dev_to_instance(dev);
MGSLPC_INFO *info = link->priv;
link->state &= ~DEV_SUSPEND;
if (link->state & DEV_CONFIG)
pcmcia_request_configuration(link->handle, &link->conf);
info->stop = 0;
return 0;
}
static int mgslpc_event(event_t event, int priority, static int mgslpc_event(event_t event, int priority,
event_callback_args_t *args) event_callback_args_t *args)
{ {
dev_link_t *link = args->client_data; dev_link_t *link = args->client_data;
MGSLPC_INFO *info = link->priv;
if (debug_level >= DEBUG_LEVEL_INFO) if (debug_level >= DEBUG_LEVEL_INFO)
printk("mgslpc_event(0x%06x)\n", event); printk("mgslpc_event(0x%06x)\n", event);
@ -794,23 +820,6 @@ static int mgslpc_event(event_t event, int priority,
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
mgslpc_config(link); mgslpc_config(link);
break; break;
case CS_EVENT_PM_SUSPEND:
link->state |= DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_RESET_PHYSICAL:
/* Mark the device as stopped, to block IO until later */
info->stop = 1;
if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle);
break;
case CS_EVENT_PM_RESUME:
link->state &= ~DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_CARD_RESET:
if (link->state & DEV_CONFIG)
pcmcia_request_configuration(link->handle, &link->conf);
info->stop = 0;
break;
} }
return 0; return 0;
} }
@ -3095,6 +3104,8 @@ static struct pcmcia_driver mgslpc_driver = {
.event = mgslpc_event, .event = mgslpc_event,
.detach = mgslpc_detach, .detach = mgslpc_detach,
.id_table = mgslpc_ids, .id_table = mgslpc_ids,
.suspend = mgslpc_suspend,
.resume = mgslpc_resume,
}; };
static struct tty_operations mgslpc_ops = { static struct tty_operations mgslpc_ops = {

View File

@ -406,6 +406,28 @@ void ide_release(dev_link_t *link)
} /* ide_release */ } /* ide_release */
static int ide_suspend(struct pcmcia_device *dev)
{
dev_link_t *link = dev_to_instance(dev);
link->state |= DEV_SUSPEND;
if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle);
return 0;
}
static int ide_resume(struct pcmcia_device *dev)
{
dev_link_t *link = dev_to_instance(dev);
link->state &= ~DEV_SUSPEND;
if (DEV_OK(link))
pcmcia_request_configuration(link->handle, &link->conf);
return 0;
}
/*====================================================================== /*======================================================================
The card status event handler. Mostly, this schedules other The card status event handler. Mostly, this schedules other
@ -432,20 +454,6 @@ int ide_event(event_t event, int priority,
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
ide_config(link); ide_config(link);
break; break;
case CS_EVENT_PM_SUSPEND:
link->state |= DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_RESET_PHYSICAL:
if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle);
break;
case CS_EVENT_PM_RESUME:
link->state &= ~DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_CARD_RESET:
if (DEV_OK(link))
pcmcia_request_configuration(link->handle, &link->conf);
break;
} }
return 0; return 0;
} /* ide_event */ } /* ide_event */
@ -498,6 +506,8 @@ static struct pcmcia_driver ide_cs_driver = {
.event = ide_event, .event = ide_event,
.detach = ide_detach, .detach = ide_detach,
.id_table = ide_ids, .id_table = ide_ids,
.suspend = ide_suspend,
.resume = ide_resume,
}; };
static int __init init_ide_cs(void) static int __init init_ide_cs(void)

View File

@ -430,6 +430,28 @@ static void avmcs_release(dev_link_t *link)
} /* avmcs_release */ } /* avmcs_release */
static int avmcs_suspend(struct pcmcia_device *dev)
{
dev_link_t *link = dev_to_instance(dev);
link->state |= DEV_SUSPEND;
if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle);
return 0;
}
static int avmcs_resume(struct pcmcia_device *dev)
{
dev_link_t *link = dev_to_instance(dev);
link->state &= ~DEV_SUSPEND;
if (link->state & DEV_CONFIG)
pcmcia_request_configuration(link->handle, &link->conf);
return 0;
}
/*====================================================================== /*======================================================================
The card status event handler. Mostly, this schedules other The card status event handler. Mostly, this schedules other
@ -459,20 +481,6 @@ static int avmcs_event(event_t event, int priority,
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
avmcs_config(link); avmcs_config(link);
break; break;
case CS_EVENT_PM_SUSPEND:
link->state |= DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_RESET_PHYSICAL:
if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle);
break;
case CS_EVENT_PM_RESUME:
link->state &= ~DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_CARD_RESET:
if (link->state & DEV_CONFIG)
pcmcia_request_configuration(link->handle, &link->conf);
break;
} }
return 0; return 0;
} /* avmcs_event */ } /* avmcs_event */
@ -494,6 +502,8 @@ static struct pcmcia_driver avmcs_driver = {
.event = avmcs_event, .event = avmcs_event,
.detach = avmcs_detach, .detach = avmcs_detach,
.id_table = avmcs_ids, .id_table = avmcs_ids,
.suspend= avmcs_suspend,
.resume = avmcs_resume,
}; };
static int __init avmcs_init(void) static int __init avmcs_init(void)

View File

@ -445,6 +445,28 @@ static void avma1cs_release(dev_link_t *link)
avma1cs_detach(link); avma1cs_detach(link);
} /* avma1cs_release */ } /* avma1cs_release */
static int avma1cs_suspend(struct pcmcia_device *dev)
{
dev_link_t *link = dev_to_instance(dev);
link->state |= DEV_SUSPEND;
if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle);
return 0;
}
static int avma1cs_resume(struct pcmcia_device *dev)
{
dev_link_t *link = dev_to_instance(dev);
link->state &= ~DEV_SUSPEND;
if (link->state & DEV_CONFIG)
pcmcia_request_configuration(link->handle, &link->conf);
return 0;
}
/*====================================================================== /*======================================================================
The card status event handler. Mostly, this schedules other The card status event handler. Mostly, this schedules other
@ -475,20 +497,6 @@ static int avma1cs_event(event_t event, int priority,
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
avma1cs_config(link); avma1cs_config(link);
break; break;
case CS_EVENT_PM_SUSPEND:
link->state |= DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_RESET_PHYSICAL:
if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle);
break;
case CS_EVENT_PM_RESUME:
link->state &= ~DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_CARD_RESET:
if (link->state & DEV_CONFIG)
pcmcia_request_configuration(link->handle, &link->conf);
break;
} }
return 0; return 0;
} /* avma1cs_event */ } /* avma1cs_event */
@ -509,6 +517,8 @@ static struct pcmcia_driver avma1cs_driver = {
.event = avma1cs_event, .event = avma1cs_event,
.detach = avma1cs_detach, .detach = avma1cs_detach,
.id_table = avma1cs_ids, .id_table = avma1cs_ids,
.suspend = avma1cs_suspend,
.resume = avma1cs_resume,
}; };
/*====================================================================*/ /*====================================================================*/

View File

@ -447,6 +447,32 @@ static void elsa_cs_release(dev_link_t *link)
link->state &= ~DEV_CONFIG; link->state &= ~DEV_CONFIG;
} /* elsa_cs_release */ } /* elsa_cs_release */
static int elsa_suspend(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
local_info_t *dev = link->priv;
link->state |= DEV_SUSPEND;
dev->busy = 1;
if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle);
return 0;
}
static int elsa_resume(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
local_info_t *dev = link->priv;
link->state &= ~DEV_SUSPEND;
if (link->state & DEV_CONFIG)
pcmcia_request_configuration(link->handle, &link->conf);
dev->busy = 0;
return 0;
}
/*====================================================================== /*======================================================================
The card status event handler. Mostly, this schedules other The card status event handler. Mostly, this schedules other
@ -465,7 +491,6 @@ static int elsa_cs_event(event_t event, int priority,
event_callback_args_t *args) event_callback_args_t *args)
{ {
dev_link_t *link = args->client_data; dev_link_t *link = args->client_data;
local_info_t *dev = link->priv;
DEBUG(1, "elsa_cs_event(%d)\n", event); DEBUG(1, "elsa_cs_event(%d)\n", event);
@ -481,23 +506,6 @@ static int elsa_cs_event(event_t event, int priority,
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
elsa_cs_config(link); elsa_cs_config(link);
break; break;
case CS_EVENT_PM_SUSPEND:
link->state |= DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_RESET_PHYSICAL:
/* Mark the device as stopped, to block IO until later */
dev->busy = 1;
if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle);
break;
case CS_EVENT_PM_RESUME:
link->state &= ~DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_CARD_RESET:
if (link->state & DEV_CONFIG)
pcmcia_request_configuration(link->handle, &link->conf);
dev->busy = 0;
break;
} }
return 0; return 0;
} /* elsa_cs_event */ } /* elsa_cs_event */
@ -518,6 +526,8 @@ static struct pcmcia_driver elsa_cs_driver = {
.event = elsa_cs_event, .event = elsa_cs_event,
.detach = elsa_cs_detach, .detach = elsa_cs_detach,
.id_table = elsa_ids, .id_table = elsa_ids,
.suspend = elsa_suspend,
.resume = elsa_resume,
}; };
static int __init init_elsa_cs(void) static int __init init_elsa_cs(void)

View File

@ -553,6 +553,32 @@ static void sedlbauer_release(dev_link_t *link)
} /* sedlbauer_release */ } /* sedlbauer_release */
static int sedlbauer_suspend(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
local_info_t *dev = link->priv;
link->state |= DEV_SUSPEND;
dev->stop = 1;
if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle);
return 0;
}
static int sedlbauer_resume(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
local_info_t *dev = link->priv;
link->state &= ~DEV_SUSPEND;
if (link->state & DEV_CONFIG)
pcmcia_request_configuration(link->handle, &link->conf);
dev->stop = 0;
return 0;
}
/*====================================================================== /*======================================================================
The card status event handler. Mostly, this schedules other The card status event handler. Mostly, this schedules other
@ -569,7 +595,6 @@ static int sedlbauer_event(event_t event, int priority,
event_callback_args_t *args) event_callback_args_t *args)
{ {
dev_link_t *link = args->client_data; dev_link_t *link = args->client_data;
local_info_t *dev = link->priv;
DEBUG(1, "sedlbauer_event(0x%06x)\n", event); DEBUG(1, "sedlbauer_event(0x%06x)\n", event);
@ -585,27 +610,6 @@ static int sedlbauer_event(event_t event, int priority,
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
sedlbauer_config(link); sedlbauer_config(link);
break; break;
case CS_EVENT_PM_SUSPEND:
link->state |= DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_RESET_PHYSICAL:
/* Mark the device as stopped, to block IO until later */
dev->stop = 1;
if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle);
break;
case CS_EVENT_PM_RESUME:
link->state &= ~DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_CARD_RESET:
if (link->state & DEV_CONFIG)
pcmcia_request_configuration(link->handle, &link->conf);
dev->stop = 0;
/*
In a normal driver, additional code may go here to restore
the device state and restart IO.
*/
break;
} }
return 0; return 0;
} /* sedlbauer_event */ } /* sedlbauer_event */
@ -631,6 +635,8 @@ static struct pcmcia_driver sedlbauer_driver = {
.event = sedlbauer_event, .event = sedlbauer_event,
.detach = sedlbauer_detach, .detach = sedlbauer_detach,
.id_table = sedlbauer_ids, .id_table = sedlbauer_ids,
.suspend = sedlbauer_suspend,
.resume = sedlbauer_resume,
}; };
static int __init init_sedlbauer_cs(void) static int __init init_sedlbauer_cs(void)

View File

@ -428,6 +428,32 @@ static void teles_cs_release(dev_link_t *link)
link->state &= ~DEV_CONFIG; link->state &= ~DEV_CONFIG;
} /* teles_cs_release */ } /* teles_cs_release */
static int teles_suspend(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
local_info_t *dev = link->priv;
link->state |= DEV_SUSPEND;
dev->busy = 1;
if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle);
return 0;
}
static int teles_resume(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
local_info_t *dev = link->priv;
link->state &= ~DEV_SUSPEND;
if (link->state & DEV_CONFIG)
pcmcia_request_configuration(link->handle, &link->conf);
dev->busy = 0;
return 0;
}
/*====================================================================== /*======================================================================
The card status event handler. Mostly, this schedules other The card status event handler. Mostly, this schedules other
@ -446,7 +472,6 @@ static int teles_cs_event(event_t event, int priority,
event_callback_args_t *args) event_callback_args_t *args)
{ {
dev_link_t *link = args->client_data; dev_link_t *link = args->client_data;
local_info_t *dev = link->priv;
DEBUG(1, "teles_cs_event(%d)\n", event); DEBUG(1, "teles_cs_event(%d)\n", event);
@ -462,23 +487,6 @@ static int teles_cs_event(event_t event, int priority,
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
teles_cs_config(link); teles_cs_config(link);
break; break;
case CS_EVENT_PM_SUSPEND:
link->state |= DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_RESET_PHYSICAL:
/* Mark the device as stopped, to block IO until later */
dev->busy = 1;
if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle);
break;
case CS_EVENT_PM_RESUME:
link->state &= ~DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_CARD_RESET:
if (link->state & DEV_CONFIG)
pcmcia_request_configuration(link->handle, &link->conf);
dev->busy = 0;
break;
} }
return 0; return 0;
} /* teles_cs_event */ } /* teles_cs_event */
@ -498,6 +506,8 @@ static struct pcmcia_driver teles_cs_driver = {
.event = teles_cs_event, .event = teles_cs_event,
.detach = teles_detach, .detach = teles_detach,
.id_table = teles_ids, .id_table = teles_ids,
.suspend = teles_suspend,
.resume = teles_resume,
}; };
static int __init init_teles_cs(void) static int __init init_teles_cs(void)

View File

@ -691,6 +691,24 @@ static void pcmciamtd_config(dev_link_t *link)
} }
static int pcmciamtd_suspend(struct pcmcia_device *dev)
{
DEBUG(2, "EVENT_PM_RESUME");
/* get_lock(link); */
return 0;
}
static int pcmciamtd_resume(struct pcmcia_device *dev)
{
DEBUG(2, "EVENT_PM_SUSPEND");
/* free_lock(link); */
return 0;
}
/* The card status event handler. Mostly, this schedules other /* The card status event handler. Mostly, this schedules other
* stuff to run after an event is received. A CARD_REMOVAL event * stuff to run after an event is received. A CARD_REMOVAL event
* also sets some flags to discourage the driver from trying * also sets some flags to discourage the driver from trying
@ -721,22 +739,6 @@ static int pcmciamtd_event(event_t event, int priority,
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
pcmciamtd_config(link); pcmciamtd_config(link);
break; break;
case CS_EVENT_PM_SUSPEND:
DEBUG(2, "EVENT_PM_SUSPEND");
link->state |= DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_RESET_PHYSICAL:
DEBUG(2, "EVENT_RESET_PHYSICAL");
/* get_lock(link); */
break;
case CS_EVENT_PM_RESUME:
DEBUG(2, "EVENT_PM_RESUME");
link->state &= ~DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_CARD_RESET:
DEBUG(2, "EVENT_CARD_RESET");
/* free_lock(link); */
break;
default: default:
DEBUG(2, "Unknown event %d", event); DEBUG(2, "Unknown event %d", event);
} }
@ -848,6 +850,8 @@ static struct pcmcia_driver pcmciamtd_driver = {
.detach = pcmciamtd_detach, .detach = pcmciamtd_detach,
.owner = THIS_MODULE, .owner = THIS_MODULE,
.id_table = pcmciamtd_ids, .id_table = pcmciamtd_ids,
.suspend = pcmciamtd_suspend,
.resume = pcmciamtd_resume,
}; };

View File

@ -547,6 +547,38 @@ static void tc574_release(dev_link_t *link)
link->state &= ~DEV_CONFIG; link->state &= ~DEV_CONFIG;
} }
static int tc574_suspend(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = link->priv;
link->state |= DEV_SUSPEND;
if (link->state & DEV_CONFIG) {
if (link->open)
netif_device_detach(dev);
pcmcia_release_configuration(link->handle);
}
return 0;
}
static int tc574_resume(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = link->priv;
link->state &= ~DEV_SUSPEND;
if (link->state & DEV_CONFIG) {
pcmcia_request_configuration(link->handle, &link->conf);
if (link->open) {
tc574_reset(dev);
netif_device_attach(dev);
}
}
return 0;
}
/* /*
The card status event handler. Mostly, this schedules other The card status event handler. Mostly, this schedules other
stuff to run after an event is received. A CARD_REMOVAL event stuff to run after an event is received. A CARD_REMOVAL event
@ -572,28 +604,6 @@ static int tc574_event(event_t event, int priority,
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
tc574_config(link); tc574_config(link);
break; break;
case CS_EVENT_PM_SUSPEND:
link->state |= DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_RESET_PHYSICAL:
if (link->state & DEV_CONFIG) {
if (link->open)
netif_device_detach(dev);
pcmcia_release_configuration(link->handle);
}
break;
case CS_EVENT_PM_RESUME:
link->state &= ~DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_CARD_RESET:
if (link->state & DEV_CONFIG) {
pcmcia_request_configuration(link->handle, &link->conf);
if (link->open) {
tc574_reset(dev);
netif_device_attach(dev);
}
}
break;
} }
return 0; return 0;
} /* tc574_event */ } /* tc574_event */
@ -1296,6 +1306,8 @@ static struct pcmcia_driver tc574_driver = {
.event = tc574_event, .event = tc574_event,
.detach = tc574_detach, .detach = tc574_detach,
.id_table = tc574_ids, .id_table = tc574_ids,
.suspend = tc574_suspend,
.resume = tc574_resume,
}; };
static int __init init_tc574(void) static int __init init_tc574(void)

View File

@ -421,6 +421,38 @@ static void tc589_release(dev_link_t *link)
link->state &= ~DEV_CONFIG; link->state &= ~DEV_CONFIG;
} }
static int tc589_suspend(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = link->priv;
link->state |= DEV_SUSPEND;
if (link->state & DEV_CONFIG) {
if (link->open)
netif_device_detach(dev);
pcmcia_release_configuration(link->handle);
}
return 0;
}
static int tc589_resume(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = link->priv;
link->state &= ~DEV_SUSPEND;
if (link->state & DEV_CONFIG) {
pcmcia_request_configuration(link->handle, &link->conf);
if (link->open) {
tc589_reset(dev);
netif_device_attach(dev);
}
}
return 0;
}
/*====================================================================== /*======================================================================
The card status event handler. Mostly, this schedules other The card status event handler. Mostly, this schedules other
@ -448,28 +480,6 @@ static int tc589_event(event_t event, int priority,
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
tc589_config(link); tc589_config(link);
break; break;
case CS_EVENT_PM_SUSPEND:
link->state |= DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_RESET_PHYSICAL:
if (link->state & DEV_CONFIG) {
if (link->open)
netif_device_detach(dev);
pcmcia_release_configuration(link->handle);
}
break;
case CS_EVENT_PM_RESUME:
link->state &= ~DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_CARD_RESET:
if (link->state & DEV_CONFIG) {
pcmcia_request_configuration(link->handle, &link->conf);
if (link->open) {
tc589_reset(dev);
netif_device_attach(dev);
}
}
break;
} }
return 0; return 0;
} /* tc589_event */ } /* tc589_event */
@ -1071,6 +1081,8 @@ static struct pcmcia_driver tc589_driver = {
.event = tc589_event, .event = tc589_event,
.detach = tc589_detach, .detach = tc589_detach,
.id_table = tc589_ids, .id_table = tc589_ids,
.suspend = tc589_suspend,
.resume = tc589_resume,
}; };
static int __init init_tc589(void) static int __init init_tc589(void)

View File

@ -490,6 +490,40 @@ static void axnet_release(dev_link_t *link)
link->state &= ~DEV_CONFIG; link->state &= ~DEV_CONFIG;
} }
static int axnet_suspend(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = link->priv;
link->state |= DEV_SUSPEND;
if (link->state & DEV_CONFIG) {
if (link->open)
netif_device_detach(dev);
pcmcia_release_configuration(link->handle);
}
return 0;
}
static int axnet_resume(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = link->priv;
link->state &= ~DEV_SUSPEND;
if (link->state & DEV_CONFIG) {
pcmcia_request_configuration(link->handle, &link->conf);
if (link->open) {
axnet_reset_8390(dev);
AX88190_init(dev, 1);
netif_device_attach(dev);
}
}
return 0;
}
/*====================================================================== /*======================================================================
The card status event handler. Mostly, this schedules other The card status event handler. Mostly, this schedules other
@ -517,29 +551,6 @@ static int axnet_event(event_t event, int priority,
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
axnet_config(link); axnet_config(link);
break; break;
case CS_EVENT_PM_SUSPEND:
link->state |= DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_RESET_PHYSICAL:
if (link->state & DEV_CONFIG) {
if (link->open)
netif_device_detach(dev);
pcmcia_release_configuration(link->handle);
}
break;
case CS_EVENT_PM_RESUME:
link->state &= ~DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_CARD_RESET:
if (link->state & DEV_CONFIG) {
pcmcia_request_configuration(link->handle, &link->conf);
if (link->open) {
axnet_reset_8390(dev);
AX88190_init(dev, 1);
netif_device_attach(dev);
}
}
break;
} }
return 0; return 0;
} /* axnet_event */ } /* axnet_event */
@ -881,6 +892,8 @@ static struct pcmcia_driver axnet_cs_driver = {
.event = axnet_event, .event = axnet_event,
.detach = axnet_detach, .detach = axnet_detach,
.id_table = axnet_ids, .id_table = axnet_ids,
.suspend = axnet_suspend,
.resume = axnet_resume,
}; };
static int __init init_axnet_cs(void) static int __init init_axnet_cs(void)

View File

@ -421,6 +421,42 @@ static void com20020_release(dev_link_t *link)
link->state &= ~(DEV_CONFIG | DEV_RELEASE_PENDING); link->state &= ~(DEV_CONFIG | DEV_RELEASE_PENDING);
} }
static int com20020_suspend(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
com20020_dev_t *info = link->priv;
struct net_device *dev = info->dev;
link->state |= DEV_SUSPEND;
if (link->state & DEV_CONFIG) {
if (link->open) {
netif_device_detach(dev);
}
pcmcia_release_configuration(link->handle);
}
return 0;
}
static int com20020_resume(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
com20020_dev_t *info = link->priv;
struct net_device *dev = info->dev;
link->state &= ~DEV_SUSPEND;
if (link->state & DEV_CONFIG) {
pcmcia_request_configuration(link->handle, &link->conf);
if (link->open) {
int ioaddr = dev->base_addr;
struct arcnet_local *lp = dev->priv;
ARCRESET;
}
}
return 0;
}
/*====================================================================== /*======================================================================
The card status event handler. Mostly, this schedules other The card status event handler. Mostly, this schedules other
@ -449,30 +485,6 @@ static int com20020_event(event_t event, int priority,
link->state |= DEV_PRESENT; link->state |= DEV_PRESENT;
com20020_config(link); com20020_config(link);
break; break;
case CS_EVENT_PM_SUSPEND:
link->state |= DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_RESET_PHYSICAL:
if (link->state & DEV_CONFIG) {
if (link->open) {
netif_device_detach(dev);
}
pcmcia_release_configuration(link->handle);
}
break;
case CS_EVENT_PM_RESUME:
link->state &= ~DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_CARD_RESET:
if (link->state & DEV_CONFIG) {
pcmcia_request_configuration(link->handle, &link->conf);
if (link->open) {
int ioaddr = dev->base_addr;
struct arcnet_local *lp = dev->priv;
ARCRESET;
}
}
break;
} }
return 0; return 0;
} /* com20020_event */ } /* com20020_event */
@ -492,6 +504,8 @@ static struct pcmcia_driver com20020_cs_driver = {
.event = com20020_event, .event = com20020_event,
.detach = com20020_detach, .detach = com20020_detach,
.id_table = com20020_ids, .id_table = com20020_ids,
.suspend = com20020_suspend,
.resume = com20020_resume,
}; };
static int __init init_com20020_cs(void) static int __init init_com20020_cs(void)

View File

@ -713,6 +713,39 @@ static void fmvj18x_release(dev_link_t *link)
link->state &= ~DEV_CONFIG; link->state &= ~DEV_CONFIG;
} }
static int fmvj18x_suspend(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = link->priv;
link->state |= DEV_SUSPEND;
if (link->state & DEV_CONFIG) {
if (link->open)
netif_device_detach(dev);
pcmcia_release_configuration(link->handle);
}
return 0;
}
static int fmvj18x_resume(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = link->priv;
link->state &= ~DEV_SUSPEND;
if (link->state & DEV_CONFIG) {
pcmcia_request_configuration(link->handle, &link->conf);
if (link->open) {
fjn_reset(dev);
netif_device_attach(dev);
}
}
return 0;
}
/*====================================================================*/ /*====================================================================*/
static int fmvj18x_event(event_t event, int priority, static int fmvj18x_event(event_t event, int priority,
@ -733,28 +766,6 @@ static int fmvj18x_event(event_t event, int priority,
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
fmvj18x_config(link); fmvj18x_config(link);
break; break;
case CS_EVENT_PM_SUSPEND:
link->state |= DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_RESET_PHYSICAL:
if (link->state & DEV_CONFIG) {
if (link->open)
netif_device_detach(dev);
pcmcia_release_configuration(link->handle);
}
break;
case CS_EVENT_PM_RESUME:
link->state &= ~DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_CARD_RESET:
if (link->state & DEV_CONFIG) {
pcmcia_request_configuration(link->handle, &link->conf);
if (link->open) {
fjn_reset(dev);
netif_device_attach(dev);
}
}
break;
} }
return 0; return 0;
} /* fmvj18x_event */ } /* fmvj18x_event */
@ -793,6 +804,8 @@ static struct pcmcia_driver fmvj18x_cs_driver = {
.event = fmvj18x_event, .event = fmvj18x_event,
.detach = fmvj18x_detach, .detach = fmvj18x_detach,
.id_table = fmvj18x_ids, .id_table = fmvj18x_ids,
.suspend = fmvj18x_suspend,
.resume = fmvj18x_resume,
}; };
static int __init init_fmvj18x_cs(void) static int __init init_fmvj18x_cs(void)

View File

@ -401,6 +401,41 @@ static void ibmtr_release(dev_link_t *link)
link->state &= ~DEV_CONFIG; link->state &= ~DEV_CONFIG;
} }
static int ibmtr_suspend(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
ibmtr_dev_t *info = link->priv;
struct net_device *dev = info->dev;
link->state |= DEV_SUSPEND;
if (link->state & DEV_CONFIG) {
if (link->open)
netif_device_detach(dev);
pcmcia_release_configuration(link->handle);
}
return 0;
}
static int ibmtr_resume(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
ibmtr_dev_t *info = link->priv;
struct net_device *dev = info->dev;
link->state &= ~DEV_SUSPEND;
if (link->state & DEV_CONFIG) {
pcmcia_request_configuration(link->handle, &link->conf);
if (link->open) {
ibmtr_probe(dev); /* really? */
netif_device_attach(dev);
}
}
return 0;
}
/*====================================================================== /*======================================================================
The card status event handler. Mostly, this schedules other The card status event handler. Mostly, this schedules other
@ -433,28 +468,6 @@ static int ibmtr_event(event_t event, int priority,
link->state |= DEV_PRESENT; link->state |= DEV_PRESENT;
ibmtr_config(link); ibmtr_config(link);
break; break;
case CS_EVENT_PM_SUSPEND:
link->state |= DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_RESET_PHYSICAL:
if (link->state & DEV_CONFIG) {
if (link->open)
netif_device_detach(dev);
pcmcia_release_configuration(link->handle);
}
break;
case CS_EVENT_PM_RESUME:
link->state &= ~DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_CARD_RESET:
if (link->state & DEV_CONFIG) {
pcmcia_request_configuration(link->handle, &link->conf);
if (link->open) {
ibmtr_probe(dev); /* really? */
netif_device_attach(dev);
}
}
break;
} }
return 0; return 0;
} /* ibmtr_event */ } /* ibmtr_event */
@ -518,6 +531,8 @@ static struct pcmcia_driver ibmtr_cs_driver = {
.event = ibmtr_event, .event = ibmtr_event,
.detach = ibmtr_detach, .detach = ibmtr_detach,
.id_table = ibmtr_ids, .id_table = ibmtr_ids,
.suspend = ibmtr_suspend,
.resume = ibmtr_resume,
}; };
static int __init init_ibmtr_cs(void) static int __init init_ibmtr_cs(void)

View File

@ -801,6 +801,39 @@ static void nmclan_release(dev_link_t *link)
link->state &= ~DEV_CONFIG; link->state &= ~DEV_CONFIG;
} }
static int nmclan_suspend(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = link->priv;
link->state |= DEV_SUSPEND;
if (link->state & DEV_CONFIG) {
if (link->open)
netif_device_detach(dev);
pcmcia_release_configuration(link->handle);
}
return 0;
}
static int nmclan_resume(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = link->priv;
link->state &= ~DEV_SUSPEND;
if (link->state & DEV_CONFIG) {
pcmcia_request_configuration(link->handle, &link->conf);
if (link->open) {
nmclan_reset(dev);
netif_device_attach(dev);
}
}
return 0;
}
/* ---------------------------------------------------------------------------- /* ----------------------------------------------------------------------------
nmclan_event nmclan_event
The card status event handler. Mostly, this schedules other The card status event handler. Mostly, this schedules other
@ -826,28 +859,6 @@ static int nmclan_event(event_t event, int priority,
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
nmclan_config(link); nmclan_config(link);
break; break;
case CS_EVENT_PM_SUSPEND:
link->state |= DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_RESET_PHYSICAL:
if (link->state & DEV_CONFIG) {
if (link->open)
netif_device_detach(dev);
pcmcia_release_configuration(link->handle);
}
break;
case CS_EVENT_PM_RESUME:
link->state &= ~DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_CARD_RESET:
if (link->state & DEV_CONFIG) {
pcmcia_request_configuration(link->handle, &link->conf);
if (link->open) {
nmclan_reset(dev);
netif_device_attach(dev);
}
}
break;
case CS_EVENT_RESET_REQUEST: case CS_EVENT_RESET_REQUEST:
return 1; return 1;
break; break;
@ -1685,6 +1696,8 @@ static struct pcmcia_driver nmclan_cs_driver = {
.event = nmclan_event, .event = nmclan_event,
.detach = nmclan_detach, .detach = nmclan_detach,
.id_table = nmclan_ids, .id_table = nmclan_ids,
.suspend = nmclan_suspend,
.resume = nmclan_resume,
}; };
static int __init init_nmclan_cs(void) static int __init init_nmclan_cs(void)

View File

@ -780,6 +780,39 @@ static void pcnet_release(dev_link_t *link)
======================================================================*/ ======================================================================*/
static int pcnet_suspend(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = link->priv;
link->state |= DEV_SUSPEND;
if (link->state & DEV_CONFIG) {
if (link->open)
netif_device_detach(dev);
pcmcia_release_configuration(link->handle);
}
return 0;
}
static int pcnet_resume(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = link->priv;
link->state &= ~DEV_SUSPEND;
if (link->state & DEV_CONFIG) {
pcmcia_request_configuration(link->handle, &link->conf);
if (link->open) {
pcnet_reset_8390(dev);
NS8390_init(dev, 1);
netif_device_attach(dev);
}
}
return 0;
}
static int pcnet_event(event_t event, int priority, static int pcnet_event(event_t event, int priority,
event_callback_args_t *args) event_callback_args_t *args)
{ {
@ -798,29 +831,6 @@ static int pcnet_event(event_t event, int priority,
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
pcnet_config(link); pcnet_config(link);
break; break;
case CS_EVENT_PM_SUSPEND:
link->state |= DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_RESET_PHYSICAL:
if (link->state & DEV_CONFIG) {
if (link->open)
netif_device_detach(dev);
pcmcia_release_configuration(link->handle);
}
break;
case CS_EVENT_PM_RESUME:
link->state &= ~DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_CARD_RESET:
if (link->state & DEV_CONFIG) {
pcmcia_request_configuration(link->handle, &link->conf);
if (link->open) {
pcnet_reset_8390(dev);
NS8390_init(dev, 1);
netif_device_attach(dev);
}
}
break;
} }
return 0; return 0;
} /* pcnet_event */ } /* pcnet_event */
@ -1849,6 +1859,8 @@ static struct pcmcia_driver pcnet_driver = {
.detach = pcnet_detach, .detach = pcnet_detach,
.owner = THIS_MODULE, .owner = THIS_MODULE,
.id_table = pcnet_ids, .id_table = pcnet_ids,
.suspend = pcnet_suspend,
.resume = pcnet_resume,
}; };
static int __init init_pcnet_cs(void) static int __init init_pcnet_cs(void)

View File

@ -895,6 +895,62 @@ free_cfg_mem:
return rc; return rc;
} }
static int smc91c92_suspend(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = link->priv;
link->state |= DEV_SUSPEND;
if (link->state & DEV_CONFIG) {
if (link->open)
netif_device_detach(dev);
pcmcia_release_configuration(link->handle);
}
return 0;
}
static int smc91c92_resume(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = link->priv;
struct smc_private *smc = netdev_priv(dev);
int i;
link->state &= ~DEV_SUSPEND;
if (link->state & DEV_CONFIG) {
if ((smc->manfid == MANFID_MEGAHERTZ) &&
(smc->cardid == PRODID_MEGAHERTZ_EM3288))
mhz_3288_power(link);
pcmcia_request_configuration(link->handle, &link->conf);
if (smc->manfid == MANFID_MOTOROLA)
mot_config(link);
if ((smc->manfid == MANFID_OSITECH) &&
(smc->cardid != PRODID_OSITECH_SEVEN)) {
/* Power up the card and enable interrupts */
set_bits(0x0300, dev->base_addr-0x10+OSITECH_AUI_PWR);
set_bits(0x0300, dev->base_addr-0x10+OSITECH_RESET_ISR);
}
if (((smc->manfid == MANFID_OSITECH) &&
(smc->cardid == PRODID_OSITECH_SEVEN)) ||
((smc->manfid == MANFID_PSION) &&
(smc->cardid == PRODID_PSION_NET100))) {
/* Download the Seven of Diamonds firmware */
for (i = 0; i < sizeof(__Xilinx7OD); i++) {
outb(__Xilinx7OD[i], link->io.BasePort1+2);
udelay(50);
}
}
if (link->open) {
smc_reset(dev);
netif_device_attach(dev);
}
}
return 0;
}
/*====================================================================== /*======================================================================
This verifies that the chip is some SMC91cXX variant, and returns This verifies that the chip is some SMC91cXX variant, and returns
@ -935,14 +991,12 @@ static int check_sig(dev_link_t *link)
} }
if (width) { if (width) {
event_callback_args_t args;
printk(KERN_INFO "smc91c92_cs: using 8-bit IO window.\n"); printk(KERN_INFO "smc91c92_cs: using 8-bit IO window.\n");
args.client_data = link; smc91c92_suspend(link->handle);
smc91c92_event(CS_EVENT_RESET_PHYSICAL, 0, &args);
pcmcia_release_io(link->handle, &link->io); pcmcia_release_io(link->handle, &link->io);
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
pcmcia_request_io(link->handle, &link->io); pcmcia_request_io(link->handle, &link->io);
smc91c92_event(CS_EVENT_CARD_RESET, 0, &args); smc91c92_resume(link->handle);
return check_sig(link); return check_sig(link);
} }
return -ENODEV; return -ENODEV;
@ -1184,8 +1238,6 @@ static int smc91c92_event(event_t event, int priority,
{ {
dev_link_t *link = args->client_data; dev_link_t *link = args->client_data;
struct net_device *dev = link->priv; struct net_device *dev = link->priv;
struct smc_private *smc = netdev_priv(dev);
int i;
DEBUG(1, "smc91c92_event(0x%06x)\n", event); DEBUG(1, "smc91c92_event(0x%06x)\n", event);
@ -1199,49 +1251,6 @@ static int smc91c92_event(event_t event, int priority,
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
smc91c92_config(link); smc91c92_config(link);
break; break;
case CS_EVENT_PM_SUSPEND:
link->state |= DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_RESET_PHYSICAL:
if (link->state & DEV_CONFIG) {
if (link->open)
netif_device_detach(dev);
pcmcia_release_configuration(link->handle);
}
break;
case CS_EVENT_PM_RESUME:
link->state &= ~DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_CARD_RESET:
if (link->state & DEV_CONFIG) {
if ((smc->manfid == MANFID_MEGAHERTZ) &&
(smc->cardid == PRODID_MEGAHERTZ_EM3288))
mhz_3288_power(link);
pcmcia_request_configuration(link->handle, &link->conf);
if (smc->manfid == MANFID_MOTOROLA)
mot_config(link);
if ((smc->manfid == MANFID_OSITECH) &&
(smc->cardid != PRODID_OSITECH_SEVEN)) {
/* Power up the card and enable interrupts */
set_bits(0x0300, dev->base_addr-0x10+OSITECH_AUI_PWR);
set_bits(0x0300, dev->base_addr-0x10+OSITECH_RESET_ISR);
}
if (((smc->manfid == MANFID_OSITECH) &&
(smc->cardid == PRODID_OSITECH_SEVEN)) ||
((smc->manfid == MANFID_PSION) &&
(smc->cardid == PRODID_PSION_NET100))) {
/* Download the Seven of Diamonds firmware */
for (i = 0; i < sizeof(__Xilinx7OD); i++) {
outb(__Xilinx7OD[i], link->io.BasePort1+2);
udelay(50);
}
}
if (link->open) {
smc_reset(dev);
netif_device_attach(dev);
}
}
break;
} }
return 0; return 0;
} /* smc91c92_event */ } /* smc91c92_event */
@ -2364,6 +2373,8 @@ static struct pcmcia_driver smc91c92_cs_driver = {
.event = smc91c92_event, .event = smc91c92_event,
.detach = smc91c92_detach, .detach = smc91c92_detach,
.id_table = smc91c92_ids, .id_table = smc91c92_ids,
.suspend = smc91c92_suspend,
.resume = smc91c92_resume,
}; };
static int __init init_smc91c92_cs(void) static int __init init_smc91c92_cs(void)

View File

@ -1157,6 +1157,41 @@ xirc2ps_release(dev_link_t *link)
/*====================================================================*/ /*====================================================================*/
static int xirc2ps_suspend(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = link->priv;
link->state |= DEV_SUSPEND;
if (link->state & DEV_CONFIG) {
if (link->open) {
netif_device_detach(dev);
do_powerdown(dev);
}
pcmcia_release_configuration(link->handle);
}
return 0;
}
static int xirc2ps_resume(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = link->priv;
link->state &= ~DEV_SUSPEND;
if (link->state & DEV_CONFIG) {
pcmcia_request_configuration(link->handle, &link->conf);
if (link->open) {
do_reset(dev,1);
netif_device_attach(dev);
}
}
return 0;
}
/**************** /****************
* The card status event handler. Mostly, this schedules other * The card status event handler. Mostly, this schedules other
* stuff to run after an event is received. A CARD_REMOVAL event * stuff to run after an event is received. A CARD_REMOVAL event
@ -1191,30 +1226,6 @@ xirc2ps_event(event_t event, int priority,
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
xirc2ps_config(link); xirc2ps_config(link);
break; break;
case CS_EVENT_PM_SUSPEND:
link->state |= DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_RESET_PHYSICAL:
if (link->state & DEV_CONFIG) {
if (link->open) {
netif_device_detach(dev);
do_powerdown(dev);
}
pcmcia_release_configuration(link->handle);
}
break;
case CS_EVENT_PM_RESUME:
link->state &= ~DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_CARD_RESET:
if (link->state & DEV_CONFIG) {
pcmcia_request_configuration(link->handle, &link->conf);
if (link->open) {
do_reset(dev,1);
netif_device_attach(dev);
}
}
break;
} }
return 0; return 0;
} /* xirc2ps_event */ } /* xirc2ps_event */
@ -2013,6 +2024,8 @@ static struct pcmcia_driver xirc2ps_cs_driver = {
.event = xirc2ps_event, .event = xirc2ps_event,
.detach = xirc2ps_detach, .detach = xirc2ps_detach,
.id_table = xirc2ps_ids, .id_table = xirc2ps_ids,
.suspend = xirc2ps_suspend,
.resume = xirc2ps_resume,
}; };
static int __init static int __init

View File

@ -492,6 +492,35 @@ static void airo_release(dev_link_t *link)
link->state &= ~DEV_CONFIG; link->state &= ~DEV_CONFIG;
} }
static int airo_suspend(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
local_info_t *local = link->priv;
link->state |= DEV_SUSPEND;
if (link->state & DEV_CONFIG) {
netif_device_detach(local->eth_dev);
pcmcia_release_configuration(link->handle);
}
return 0;
}
static int airo_resume(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
local_info_t *local = link->priv;
link->state &= ~DEV_SUSPEND;
if (link->state & DEV_CONFIG) {
pcmcia_request_configuration(link->handle, &link->conf);
reset_airo_card(local->eth_dev);
netif_device_attach(local->eth_dev);
}
return 0;
}
/*====================================================================== /*======================================================================
The card status event handler. Mostly, this schedules other The card status event handler. Mostly, this schedules other
@ -524,25 +553,6 @@ static int airo_event(event_t event, int priority,
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
airo_config(link); airo_config(link);
break; break;
case CS_EVENT_PM_SUSPEND:
link->state |= DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_RESET_PHYSICAL:
if (link->state & DEV_CONFIG) {
netif_device_detach(local->eth_dev);
pcmcia_release_configuration(link->handle);
}
break;
case CS_EVENT_PM_RESUME:
link->state &= ~DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_CARD_RESET:
if (link->state & DEV_CONFIG) {
pcmcia_request_configuration(link->handle, &link->conf);
reset_airo_card(local->eth_dev);
netif_device_attach(local->eth_dev);
}
break;
} }
return 0; return 0;
} /* airo_event */ } /* airo_event */
@ -565,6 +575,8 @@ static struct pcmcia_driver airo_driver = {
.event = airo_event, .event = airo_event,
.detach = airo_detach, .detach = airo_detach,
.id_table = airo_ids, .id_table = airo_ids,
.suspend = airo_suspend,
.resume = airo_resume,
}; };
static int airo_cs_init(void) static int airo_cs_init(void)

View File

@ -477,6 +477,35 @@ static void atmel_release(dev_link_t *link)
link->state &= ~DEV_CONFIG; link->state &= ~DEV_CONFIG;
} }
static int atmel_suspend(struct pcmcia_device *dev)
{
dev_link_t *link = dev_to_instance(dev);
local_info_t *local = link->priv;
link->state |= DEV_SUSPEND;
if (link->state & DEV_CONFIG) {
netif_device_detach(local->eth_dev);
pcmcia_release_configuration(link->handle);
}
return 0;
}
static int atmel_resume(struct pcmcia_device *dev)
{
dev_link_t *link = dev_to_instance(dev);
local_info_t *local = link->priv;
link->state &= ~DEV_SUSPEND;
if (link->state & DEV_CONFIG) {
pcmcia_request_configuration(link->handle, &link->conf);
atmel_open(local->eth_dev);
netif_device_attach(local->eth_dev);
}
return 0;
}
/*====================================================================== /*======================================================================
The card status event handler. Mostly, this schedules other The card status event handler. Mostly, this schedules other
@ -509,25 +538,6 @@ static int atmel_event(event_t event, int priority,
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
atmel_config(link); atmel_config(link);
break; break;
case CS_EVENT_PM_SUSPEND:
link->state |= DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_RESET_PHYSICAL:
if (link->state & DEV_CONFIG) {
netif_device_detach(local->eth_dev);
pcmcia_release_configuration(link->handle);
}
break;
case CS_EVENT_PM_RESUME:
link->state &= ~DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_CARD_RESET:
if (link->state & DEV_CONFIG) {
pcmcia_request_configuration(link->handle, &link->conf);
atmel_open(local->eth_dev);
netif_device_attach(local->eth_dev);
}
break;
} }
return 0; return 0;
} /* atmel_event */ } /* atmel_event */
@ -585,6 +595,8 @@ static struct pcmcia_driver atmel_driver = {
.event = atmel_event, .event = atmel_event,
.detach = atmel_detach, .detach = atmel_detach,
.id_table = atmel_ids, .id_table = atmel_ids,
.suspend = atmel_suspend,
.resume = atmel_resume,
}; };
static int atmel_cs_init(void) static int atmel_cs_init(void)

View File

@ -846,19 +846,63 @@ static void prism2_release(u_long arg)
PDEBUG(DEBUG_FLOW, "release - done\n"); PDEBUG(DEBUG_FLOW, "release - done\n");
} }
static int hostap_cs_suspend(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = (struct net_device *) link->priv;
int dev_open = 0;
PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_SUSPEND\n", dev_info);
link->state |= DEV_SUSPEND;
if (link->state & DEV_CONFIG) {
struct hostap_interface *iface = netdev_priv(dev);
if (iface && iface->local)
dev_open = iface->local->num_dev_open > 0;
if (dev_open) {
netif_stop_queue(dev);
netif_device_detach(dev);
}
prism2_suspend(dev);
pcmcia_release_configuration(link->handle);
}
return 0;
}
static int hostap_cs_resume(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = (struct net_device *) link->priv;
int dev_open = 0;
PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_RESUME\n", dev_info);
link->state &= ~DEV_SUSPEND;
if (link->state & DEV_CONFIG) {
struct hostap_interface *iface = netdev_priv(dev);
if (iface && iface->local)
dev_open = iface->local->num_dev_open > 0;
pcmcia_request_configuration(link->handle, &link->conf);
prism2_hw_shutdown(dev, 1);
prism2_hw_config(dev, dev_open ? 0 : 1);
if (dev_open) {
netif_device_attach(dev);
netif_start_queue(dev);
}
}
return 0;
}
static int prism2_event(event_t event, int priority, static int prism2_event(event_t event, int priority,
event_callback_args_t *args) event_callback_args_t *args)
{ {
dev_link_t *link = args->client_data; dev_link_t *link = args->client_data;
struct net_device *dev = (struct net_device *) link->priv; struct net_device *dev = (struct net_device *) link->priv;
int dev_open = 0;
if (link->state & DEV_CONFIG) {
struct hostap_interface *iface = netdev_priv(dev);
if (iface && iface->local)
dev_open = iface->local->num_dev_open > 0;
}
switch (event) { switch (event) {
case CS_EVENT_CARD_INSERTION: case CS_EVENT_CARD_INSERTION:
@ -879,42 +923,6 @@ static int prism2_event(event_t event, int priority,
} }
break; break;
case CS_EVENT_PM_SUSPEND:
PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_SUSPEND\n", dev_info);
link->state |= DEV_SUSPEND;
/* fall through */
case CS_EVENT_RESET_PHYSICAL:
PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_RESET_PHYSICAL\n", dev_info);
if (link->state & DEV_CONFIG) {
if (dev_open) {
netif_stop_queue(dev);
netif_device_detach(dev);
}
prism2_suspend(dev);
pcmcia_release_configuration(link->handle);
}
break;
case CS_EVENT_PM_RESUME:
PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_RESUME\n", dev_info);
link->state &= ~DEV_SUSPEND;
/* fall through */
case CS_EVENT_CARD_RESET:
PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_CARD_RESET\n", dev_info);
if (link->state & DEV_CONFIG) {
pcmcia_request_configuration(link->handle,
&link->conf);
prism2_hw_shutdown(dev, 1);
prism2_hw_config(dev, dev_open ? 0 : 1);
if (dev_open) {
netif_device_attach(dev);
netif_start_queue(dev);
}
}
break;
default: default:
PDEBUG(DEBUG_EXTRA, "%s: prism2_event() - unknown event %d\n", PDEBUG(DEBUG_EXTRA, "%s: prism2_event() - unknown event %d\n",
dev_info, event); dev_info, event);
@ -987,6 +995,8 @@ static struct pcmcia_driver hostap_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.event = prism2_event, .event = prism2_event,
.id_table = hostap_cs_ids, .id_table = hostap_cs_ids,
.suspend = hostap_cs_suspend,
.resume = hostap_cs_resume,
}; };
static int __init init_prism2_pccard(void) static int __init init_prism2_pccard(void)

View File

@ -935,6 +935,39 @@ static void netwave_release(dev_link_t *link)
link->state &= ~DEV_CONFIG; link->state &= ~DEV_CONFIG;
} }
static int netwave_suspend(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = link->priv;
link->state |= DEV_SUSPEND;
if (link->state & DEV_CONFIG) {
if (link->open)
netif_device_detach(dev);
pcmcia_release_configuration(link->handle);
}
return 0;
}
static int netwave_resume(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = link->priv;
link->state &= ~DEV_SUSPEND;
if (link->state & DEV_CONFIG) {
pcmcia_request_configuration(link->handle, &link->conf);
if (link->open) {
netwave_reset(dev);
netif_device_attach(dev);
}
}
return 0;
}
/* /*
* Function netwave_event (event, priority, args) * Function netwave_event (event, priority, args)
* *
@ -973,28 +1006,6 @@ static int netwave_event(event_t event, int priority,
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
netwave_pcmcia_config( link); netwave_pcmcia_config( link);
break; break;
case CS_EVENT_PM_SUSPEND:
link->state |= DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_RESET_PHYSICAL:
if (link->state & DEV_CONFIG) {
if (link->open)
netif_device_detach(dev);
pcmcia_release_configuration(link->handle);
}
break;
case CS_EVENT_PM_RESUME:
link->state &= ~DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_CARD_RESET:
if (link->state & DEV_CONFIG) {
pcmcia_request_configuration(link->handle, &link->conf);
if (link->open) {
netwave_reset(dev);
netif_device_attach(dev);
}
}
break;
} }
return 0; return 0;
} /* netwave_event */ } /* netwave_event */
@ -1495,6 +1506,8 @@ static struct pcmcia_driver netwave_driver = {
.event = netwave_event, .event = netwave_event,
.detach = netwave_detach, .detach = netwave_detach,
.id_table = netwave_ids, .id_table = netwave_ids,
.suspend = netwave_suspend,
.resume = netwave_resume,
}; };
static int __init init_netwave_cs(void) static int __init init_netwave_cs(void)

View File

@ -465,6 +465,83 @@ orinoco_cs_release(dev_link_t *link)
ioport_unmap(priv->hw.iobase); ioport_unmap(priv->hw.iobase);
} /* orinoco_cs_release */ } /* orinoco_cs_release */
static int orinoco_cs_suspend(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = link->priv;
struct orinoco_private *priv = netdev_priv(dev);
struct orinoco_pccard *card = priv->card;
int err = 0;
unsigned long flags;
link->state |= DEV_SUSPEND;
if (link->state & DEV_CONFIG) {
/* This is probably racy, but I can't think of
a better way, short of rewriting the PCMCIA
layer to not suck :-( */
if (! test_bit(0, &card->hard_reset_in_progress)) {
spin_lock_irqsave(&priv->lock, flags);
err = __orinoco_down(dev);
if (err)
printk(KERN_WARNING "%s: Error %d downing interface\n",
dev->name, err);
netif_device_detach(dev);
priv->hw_unavailable++;
spin_unlock_irqrestore(&priv->lock, flags);
}
pcmcia_release_configuration(link->handle);
}
return 0;
}
static int orinoco_cs_resume(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = link->priv;
struct orinoco_private *priv = netdev_priv(dev);
struct orinoco_pccard *card = priv->card;
int err = 0;
unsigned long flags;
link->state &= ~DEV_SUSPEND;
if (link->state & DEV_CONFIG) {
/* FIXME: should we double check that this is
* the same card as we had before */
pcmcia_request_configuration(link->handle, &link->conf);
if (! test_bit(0, &card->hard_reset_in_progress)) {
err = orinoco_reinit_firmware(dev);
if (err) {
printk(KERN_ERR "%s: Error %d re-initializing firmware\n",
dev->name, err);
return -EIO;
}
spin_lock_irqsave(&priv->lock, flags);
netif_device_attach(dev);
priv->hw_unavailable--;
if (priv->open && ! priv->hw_unavailable) {
err = __orinoco_up(dev);
if (err)
printk(KERN_ERR "%s: Error %d restarting card\n",
dev->name, err);
}
spin_unlock_irqrestore(&priv->lock, flags);
}
}
return 0;
}
/* /*
* The card status event handler. Mostly, this schedules other stuff * The card status event handler. Mostly, this schedules other stuff
* to run after an event is received. * to run after an event is received.
@ -476,9 +553,7 @@ orinoco_cs_event(event_t event, int priority,
dev_link_t *link = args->client_data; dev_link_t *link = args->client_data;
struct net_device *dev = link->priv; struct net_device *dev = link->priv;
struct orinoco_private *priv = netdev_priv(dev); struct orinoco_private *priv = netdev_priv(dev);
struct orinoco_pccard *card = priv->card;
int err = 0; int err = 0;
unsigned long flags;
switch (event) { switch (event) {
case CS_EVENT_CARD_REMOVAL: case CS_EVENT_CARD_REMOVAL:
@ -497,70 +572,6 @@ orinoco_cs_event(event_t event, int priority,
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
orinoco_cs_config(link); orinoco_cs_config(link);
break; break;
case CS_EVENT_PM_SUSPEND:
link->state |= DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_RESET_PHYSICAL:
/* Mark the device as stopped, to block IO until later */
if (link->state & DEV_CONFIG) {
/* This is probably racy, but I can't think of
a better way, short of rewriting the PCMCIA
layer to not suck :-( */
if (! test_bit(0, &card->hard_reset_in_progress)) {
spin_lock_irqsave(&priv->lock, flags);
err = __orinoco_down(dev);
if (err)
printk(KERN_WARNING "%s: %s: Error %d downing interface\n",
dev->name,
event == CS_EVENT_PM_SUSPEND ? "SUSPEND" : "RESET_PHYSICAL",
err);
netif_device_detach(dev);
priv->hw_unavailable++;
spin_unlock_irqrestore(&priv->lock, flags);
}
pcmcia_release_configuration(link->handle);
}
break;
case CS_EVENT_PM_RESUME:
link->state &= ~DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_CARD_RESET:
if (link->state & DEV_CONFIG) {
/* FIXME: should we double check that this is
* the same card as we had before */
pcmcia_request_configuration(link->handle, &link->conf);
if (! test_bit(0, &card->hard_reset_in_progress)) {
err = orinoco_reinit_firmware(dev);
if (err) {
printk(KERN_ERR "%s: Error %d re-initializing firmware\n",
dev->name, err);
break;
}
spin_lock_irqsave(&priv->lock, flags);
netif_device_attach(dev);
priv->hw_unavailable--;
if (priv->open && ! priv->hw_unavailable) {
err = __orinoco_up(dev);
if (err)
printk(KERN_ERR "%s: Error %d restarting card\n",
dev->name, err);
}
spin_unlock_irqrestore(&priv->lock, flags);
}
}
break;
} }
return err; return err;
@ -669,6 +680,8 @@ static struct pcmcia_driver orinoco_driver = {
.detach = orinoco_cs_detach, .detach = orinoco_cs_detach,
.event = orinoco_cs_event, .event = orinoco_cs_event,
.id_table = orinoco_cs_ids, .id_table = orinoco_cs_ids,
.suspend = orinoco_cs_suspend,
.resume = orinoco_cs_resume,
}; };
static int __init static int __init

View File

@ -891,6 +891,40 @@ static void ray_release(dev_link_t *link)
DEBUG(2,"ray_release ending\n"); DEBUG(2,"ray_release ending\n");
} }
static int ray_suspend(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = link->priv;
link->state |= DEV_SUSPEND;
if (link->state & DEV_CONFIG) {
if (link->open)
netif_device_detach(dev);
pcmcia_release_configuration(link->handle);
}
return 0;
}
static int ray_resume(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = link->priv;
link->state &= ~DEV_SUSPEND;
if (link->state & DEV_CONFIG) {
pcmcia_request_configuration(link->handle, &link->conf);
if (link->open) {
ray_reset(dev);
netif_device_attach(dev);
}
}
return 0;
}
/*============================================================================= /*=============================================================================
The card status event handler. Mostly, this schedules other The card status event handler. Mostly, this schedules other
stuff to run after an event is received. A CARD_REMOVAL event stuff to run after an event is received. A CARD_REMOVAL event
@ -923,29 +957,6 @@ static int ray_event(event_t event, int priority,
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
ray_config(link); ray_config(link);
break; break;
case CS_EVENT_PM_SUSPEND:
link->state |= DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_RESET_PHYSICAL:
if (link->state & DEV_CONFIG) {
if (link->open)
netif_device_detach(dev);
pcmcia_release_configuration(link->handle);
}
break;
case CS_EVENT_PM_RESUME:
link->state &= ~DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_CARD_RESET:
if (link->state & DEV_CONFIG) {
pcmcia_request_configuration(link->handle, &link->conf);
if (link->open) {
ray_reset(dev);
netif_device_attach(dev);
}
}
break;
} }
return 0; return 0;
DEBUG(2,"ray_event ending\n"); DEBUG(2,"ray_event ending\n");
@ -2949,6 +2960,8 @@ static struct pcmcia_driver ray_driver = {
.event = ray_event, .event = ray_event,
.detach = ray_detach, .detach = ray_detach,
.id_table = ray_ids, .id_table = ray_ids,
.suspend = ray_suspend,
.resume = ray_resume,
}; };
static int __init init_ray_cs(void) static int __init init_ray_cs(void)

View File

@ -948,6 +948,56 @@ spectrum_cs_release(dev_link_t *link)
ioport_unmap(priv->hw.iobase); ioport_unmap(priv->hw.iobase);
} /* spectrum_cs_release */ } /* spectrum_cs_release */
static int
spectrum_cs_suspend(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = link->priv;
struct orinoco_private *priv = netdev_priv(dev);
unsigned long flags;
int err = 0;
link->state |= DEV_SUSPEND;
/* Mark the device as stopped, to block IO until later */
if (link->state & DEV_CONFIG) {
spin_lock_irqsave(&priv->lock, flags);
err = __orinoco_down(dev);
if (err)
printk(KERN_WARNING "%s: Error %d downing interface\n",
dev->name, err);
netif_device_detach(dev);
priv->hw_unavailable++;
spin_unlock_irqrestore(&priv->lock, flags);
pcmcia_release_configuration(link->handle);
}
return 0;
}
static int
spectrum_cs_resume(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = link->priv;
struct orinoco_private *priv = netdev_priv(dev);
link->state &= ~DEV_SUSPEND;
if (link->state & DEV_CONFIG) {
/* FIXME: should we double check that this is
* the same card as we had before */
pcmcia_request_configuration(link->handle, &link->conf);
netif_device_attach(dev);
priv->hw_unavailable--;
schedule_work(&priv->reset_work);
}
return 0;
}
/* /*
* The card status event handler. Mostly, this schedules other stuff * The card status event handler. Mostly, this schedules other stuff
* to run after an event is received. * to run after an event is received.
@ -959,8 +1009,6 @@ spectrum_cs_event(event_t event, int priority,
dev_link_t *link = args->client_data; dev_link_t *link = args->client_data;
struct net_device *dev = link->priv; struct net_device *dev = link->priv;
struct orinoco_private *priv = netdev_priv(dev); struct orinoco_private *priv = netdev_priv(dev);
int err = 0;
unsigned long flags;
switch (event) { switch (event) {
case CS_EVENT_CARD_REMOVAL: case CS_EVENT_CARD_REMOVAL:
@ -980,49 +1028,9 @@ spectrum_cs_event(event_t event, int priority,
spectrum_cs_config(link); spectrum_cs_config(link);
break; break;
case CS_EVENT_PM_SUSPEND:
link->state |= DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_RESET_PHYSICAL:
/* Mark the device as stopped, to block IO until later */
if (link->state & DEV_CONFIG) {
/* This is probably racy, but I can't think of
a better way, short of rewriting the PCMCIA
layer to not suck :-( */
spin_lock_irqsave(&priv->lock, flags);
err = __orinoco_down(dev);
if (err)
printk(KERN_WARNING "%s: %s: Error %d downing interface\n",
dev->name,
event == CS_EVENT_PM_SUSPEND ? "SUSPEND" : "RESET_PHYSICAL",
err);
netif_device_detach(dev);
priv->hw_unavailable++;
spin_unlock_irqrestore(&priv->lock, flags);
pcmcia_release_configuration(link->handle);
}
break;
case CS_EVENT_PM_RESUME:
link->state &= ~DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_CARD_RESET:
if (link->state & DEV_CONFIG) {
/* FIXME: should we double check that this is
* the same card as we had before */
pcmcia_request_configuration(link->handle, &link->conf);
netif_device_attach(dev);
priv->hw_unavailable--;
schedule_work(&priv->reset_work);
}
break;
} }
return err; return 0;
} /* spectrum_cs_event */ } /* spectrum_cs_event */
/********************************************************************/ /********************************************************************/
@ -1050,6 +1058,8 @@ static struct pcmcia_driver orinoco_driver = {
}, },
.attach = spectrum_cs_attach, .attach = spectrum_cs_attach,
.detach = spectrum_cs_detach, .detach = spectrum_cs_detach,
.suspend = spectrum_cs_suspend,
.resume = spectrum_cs_resume,
.event = spectrum_cs_event, .event = spectrum_cs_event,
.id_table = spectrum_cs_ids, .id_table = spectrum_cs_ids,
}; };

View File

@ -4775,6 +4775,56 @@ wavelan_detach(dev_link_t * link)
#endif #endif
} }
static int wavelan_suspend(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
struct net_device * dev = (struct net_device *) link->priv;
/* NB: wavelan_close will be called, but too late, so we are
* obliged to close nicely the wavelan here. David, could you
* close the device before suspending them ? And, by the way,
* could you, on resume, add a "route add -net ..." after the
* ifconfig up ? Thanks... */
/* Stop receiving new messages and wait end of transmission */
wv_ru_stop(dev);
/* Power down the module */
hacr_write(dev->base_addr, HACR_DEFAULT & (~HACR_PWR_STAT));
/* The card is now suspended */
link->state |= DEV_SUSPEND;
if(link->state & DEV_CONFIG)
{
if(link->open)
netif_device_detach(dev);
pcmcia_release_configuration(link->handle);
}
return 0;
}
static int wavelan_resume(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
struct net_device * dev = (struct net_device *) link->priv;
link->state &= ~DEV_SUSPEND;
if(link->state & DEV_CONFIG)
{
pcmcia_request_configuration(link->handle, &link->conf);
if(link->open) /* If RESET -> True, If RESUME -> False ? */
{
wv_hw_reset(dev);
netif_device_attach(dev);
}
}
return 0;
}
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
/* /*
* The card status event handler. Mostly, this schedules other stuff * The card status event handler. Mostly, this schedules other stuff
@ -4832,46 +4882,6 @@ wavelan_event(event_t event, /* The event received */
else else
dev->irq = 0; dev->irq = 0;
break; break;
case CS_EVENT_PM_SUSPEND:
/* NB: wavelan_close will be called, but too late, so we are
* obliged to close nicely the wavelan here. David, could you
* close the device before suspending them ? And, by the way,
* could you, on resume, add a "route add -net ..." after the
* ifconfig up ? Thanks... */
/* Stop receiving new messages and wait end of transmission */
wv_ru_stop(dev);
/* Power down the module */
hacr_write(dev->base_addr, HACR_DEFAULT & (~HACR_PWR_STAT));
/* The card is now suspended */
link->state |= DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_RESET_PHYSICAL:
if(link->state & DEV_CONFIG)
{
if(link->open)
netif_device_detach(dev);
pcmcia_release_configuration(link->handle);
}
break;
case CS_EVENT_PM_RESUME:
link->state &= ~DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_CARD_RESET:
if(link->state & DEV_CONFIG)
{
pcmcia_request_configuration(link->handle, &link->conf);
if(link->open) /* If RESET -> True, If RESUME -> False ? */
{
wv_hw_reset(dev);
netif_device_attach(dev);
}
}
break;
} }
#ifdef DEBUG_CALLBACK_TRACE #ifdef DEBUG_CALLBACK_TRACE
@ -4898,6 +4908,8 @@ static struct pcmcia_driver wavelan_driver = {
.event = wavelan_event, .event = wavelan_event,
.detach = wavelan_detach, .detach = wavelan_detach,
.id_table = wavelan_ids, .id_table = wavelan_ids,
.suspend = wavelan_suspend,
.resume = wavelan_resume,
}; };
static int __init static int __init

View File

@ -2173,6 +2173,41 @@ static void wl3501_release(dev_link_t *link)
link->state &= ~DEV_CONFIG; link->state &= ~DEV_CONFIG;
} }
static int wl3501_suspend(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = link->priv;
link->state |= DEV_SUSPEND;
wl3501_pwr_mgmt(dev->priv, WL3501_SUSPEND);
if (link->state & DEV_CONFIG) {
if (link->open)
netif_device_detach(dev);
pcmcia_release_configuration(link->handle);
}
return 0;
}
static int wl3501_resume(struct pcmcia_device *p_dev)
{
dev_link_t *link = dev_to_instance(p_dev);
struct net_device *dev = link->priv;
wl3501_pwr_mgmt(dev->priv, WL3501_RESUME);
if (link->state & DEV_CONFIG) {
pcmcia_request_configuration(link->handle, &link->conf);
if (link->open) {
wl3501_reset(dev);
netif_device_attach(dev);
}
}
return 0;
}
/** /**
* wl3501_event - The card status event handler * wl3501_event - The card status event handler
* @event - event * @event - event
@ -2206,30 +2241,6 @@ static int wl3501_event(event_t event, int pri, event_callback_args_t *args)
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
wl3501_config(link); wl3501_config(link);
break; break;
case CS_EVENT_PM_SUSPEND:
link->state |= DEV_SUSPEND;
wl3501_pwr_mgmt(dev->priv, WL3501_SUSPEND);
/* Fall through... */
case CS_EVENT_RESET_PHYSICAL:
if (link->state & DEV_CONFIG) {
if (link->open)
netif_device_detach(dev);
pcmcia_release_configuration(link->handle);
}
break;
case CS_EVENT_PM_RESUME:
link->state &= ~DEV_SUSPEND;
wl3501_pwr_mgmt(dev->priv, WL3501_RESUME);
/* Fall through... */
case CS_EVENT_CARD_RESET:
if (link->state & DEV_CONFIG) {
pcmcia_request_configuration(link->handle, &link->conf);
if (link->open) {
wl3501_reset(dev);
netif_device_attach(dev);
}
}
break;
} }
return 0; return 0;
} }
@ -2249,6 +2260,8 @@ static struct pcmcia_driver wl3501_driver = {
.event = wl3501_event, .event = wl3501_event,
.detach = wl3501_detach, .detach = wl3501_detach,
.id_table = wl3501_ids, .id_table = wl3501_ids,
.suspend = wl3501_suspend,
.resume = wl3501_resume,
}; };
static int __init wl3501_init_module(void) static int __init wl3501_init_module(void)

View File

@ -325,6 +325,28 @@ void parport_cs_release(dev_link_t *link)
} /* parport_cs_release */ } /* parport_cs_release */
static int parport_suspend(struct pcmcia_device *dev)
{
dev_link_t *link = dev_to_instance(dev);
link->state |= DEV_SUSPEND;
if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle);
return 0;
}
static int parport_resume(struct pcmcia_device *dev)
{
dev_link_t *link = dev_to_instance(dev);
link->state &= ~DEV_SUSPEND;
if (DEV_OK(link))
pcmcia_request_configuration(link->handle, &link->conf);
return 0;
}
/*====================================================================== /*======================================================================
The card status event handler. Mostly, this schedules other The card status event handler. Mostly, this schedules other
@ -349,20 +371,6 @@ int parport_event(event_t event, int priority,
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
parport_config(link); parport_config(link);
break; break;
case CS_EVENT_PM_SUSPEND:
link->state |= DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_RESET_PHYSICAL:
if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle);
break;
case CS_EVENT_PM_RESUME:
link->state &= ~DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_CARD_RESET:
if (DEV_OK(link))
pcmcia_request_configuration(link->handle, &link->conf);
break;
} }
return 0; return 0;
} /* parport_event */ } /* parport_event */
@ -383,7 +391,8 @@ static struct pcmcia_driver parport_cs_driver = {
.event = parport_event, .event = parport_event,
.detach = parport_detach, .detach = parport_detach,
.id_table = parport_ids, .id_table = parport_ids,
.suspend = parport_suspend,
.resume = parport_resume,
}; };
static int __init init_parport_cs(void) static int __init init_parport_cs(void)

View File

@ -951,6 +951,16 @@ static int send_event_callback(struct device *dev, void * _data)
if (p_dev->state & (CLIENT_UNBOUND|CLIENT_STALE)) if (p_dev->state & (CLIENT_UNBOUND|CLIENT_STALE))
return 0; return 0;
if ((data->event == CS_EVENT_PM_SUSPEND) ||
(data->event == CS_EVENT_RESET_PHYSICAL)) {
if (p_drv->suspend)
return p_drv->suspend(p_dev);
} else if ((data->event == CS_EVENT_PM_RESUME) ||
(data->event == CS_EVENT_CARD_RESET)) {
if (p_drv->resume)
return p_drv->resume(p_dev);
}
if (p_drv->event) if (p_drv->event)
return p_drv->event(data->event, data->priority, return p_drv->event(data->event, data->priority,
&p_dev->event_callback_args); &p_dev->event_callback_args);

View File

@ -272,11 +272,37 @@ static void aha152x_release_cs(dev_link_t *link)
link->state &= ~DEV_CONFIG; link->state &= ~DEV_CONFIG;
} }
static int aha152x_suspend(struct pcmcia_device *dev)
{
dev_link_t *link = dev_to_instance(dev);
link->state |= DEV_SUSPEND;
if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle);
return 0;
}
static int aha152x_resume(struct pcmcia_device *dev)
{
dev_link_t *link = dev_to_instance(dev);
scsi_info_t *info = link->priv;
link->state &= ~DEV_SUSPEND;
if (link->state & DEV_CONFIG) {
Scsi_Cmnd tmp;
pcmcia_request_configuration(link->handle, &link->conf);
tmp.device->host = info->host;
aha152x_host_reset(&tmp);
}
return 0;
}
static int aha152x_event(event_t event, int priority, static int aha152x_event(event_t event, int priority,
event_callback_args_t *args) event_callback_args_t *args)
{ {
dev_link_t *link = args->client_data; dev_link_t *link = args->client_data;
scsi_info_t *info = link->priv;
DEBUG(0, "aha152x_event(0x%06x)\n", event); DEBUG(0, "aha152x_event(0x%06x)\n", event);
@ -290,24 +316,6 @@ static int aha152x_event(event_t event, int priority,
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
aha152x_config_cs(link); aha152x_config_cs(link);
break; break;
case CS_EVENT_PM_SUSPEND:
link->state |= DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_RESET_PHYSICAL:
if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle);
break;
case CS_EVENT_PM_RESUME:
link->state &= ~DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_CARD_RESET:
if (link->state & DEV_CONFIG) {
Scsi_Cmnd tmp;
pcmcia_request_configuration(link->handle, &link->conf);
tmp.device->host = info->host;
aha152x_host_reset(&tmp);
}
break;
} }
return 0; return 0;
} }
@ -331,6 +339,8 @@ static struct pcmcia_driver aha152x_cs_driver = {
.event = aha152x_event, .event = aha152x_event,
.detach = aha152x_detach, .detach = aha152x_detach,
.id_table = aha152x_ids, .id_table = aha152x_ids,
.suspend = aha152x_suspend,
.resume = aha152x_resume,
}; };
static int __init init_aha152x_cs(void) static int __init init_aha152x_cs(void)

View File

@ -256,6 +256,30 @@ static void fdomain_release(dev_link_t *link)
/*====================================================================*/ /*====================================================================*/
static int fdomain_suspend(struct pcmcia_device *dev)
{
dev_link_t *link = dev_to_instance(dev);
link->state |= DEV_SUSPEND;
if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle);
return 0;
}
static int fdomain_resume(struct pcmcia_device *dev)
{
dev_link_t *link = dev_to_instance(dev);
link->state &= ~DEV_SUSPEND;
if (link->state & DEV_CONFIG) {
pcmcia_request_configuration(link->handle, &link->conf);
fdomain_16x0_bus_reset(NULL);
}
return 0;
}
static int fdomain_event(event_t event, int priority, static int fdomain_event(event_t event, int priority,
event_callback_args_t *args) event_callback_args_t *args)
{ {
@ -273,22 +297,6 @@ static int fdomain_event(event_t event, int priority,
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
fdomain_config(link); fdomain_config(link);
break; break;
case CS_EVENT_PM_SUSPEND:
link->state |= DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_RESET_PHYSICAL:
if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle);
break;
case CS_EVENT_PM_RESUME:
link->state &= ~DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_CARD_RESET:
if (link->state & DEV_CONFIG) {
pcmcia_request_configuration(link->handle, &link->conf);
fdomain_16x0_bus_reset(NULL);
}
break;
} }
return 0; return 0;
} /* fdomain_event */ } /* fdomain_event */
@ -311,6 +319,8 @@ static struct pcmcia_driver fdomain_cs_driver = {
.event = fdomain_event, .event = fdomain_event,
.detach = fdomain_detach, .detach = fdomain_detach,
.id_table = fdomain_ids, .id_table = fdomain_ids,
.suspend = fdomain_suspend,
.resume = fdomain_resume,
}; };
static int __init init_fdomain_cs(void) static int __init init_fdomain_cs(void)

View File

@ -2021,6 +2021,59 @@ static void nsp_cs_release(dev_link_t *link)
#endif #endif
} /* nsp_cs_release */ } /* nsp_cs_release */
static int nsp_cs_suspend(struct pcmcia_device *dev)
{
dev_link_t *link = dev_to_instance(dev);
scsi_info_t *info = link->priv;
nsp_hw_data *data;
link->state |= DEV_SUSPEND;
nsp_dbg(NSP_DEBUG_INIT, "event: suspend");
if (info->host != NULL) {
nsp_msg(KERN_INFO, "clear SDTR status");
data = (nsp_hw_data *)info->host->hostdata;
nsphw_init_sync(data);
}
info->stop = 1;
if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle);
return 0;
}
static int nsp_cs_resume(struct pcmcia_device *dev)
{
dev_link_t *link = dev_to_instance(dev);
scsi_info_t *info = link->priv;
nsp_hw_data *data;
nsp_dbg(NSP_DEBUG_INIT, "event: resume");
link->state &= ~DEV_SUSPEND;
if (link->state & DEV_CONFIG)
pcmcia_request_configuration(link->handle, &link->conf);
info->stop = 0;
if (info->host != NULL) {
nsp_msg(KERN_INFO, "reset host and bus");
data = (nsp_hw_data *)info->host->hostdata;
nsphw_init (data);
nsp_bus_reset(data);
}
return 0;
}
/*====================================================================== /*======================================================================
The card status event handler. Mostly, this schedules other The card status event handler. Mostly, this schedules other
@ -2039,8 +2092,6 @@ static int nsp_cs_event(event_t event,
event_callback_args_t *args) event_callback_args_t *args)
{ {
dev_link_t *link = args->client_data; dev_link_t *link = args->client_data;
scsi_info_t *info = link->priv;
nsp_hw_data *data;
nsp_dbg(NSP_DEBUG_INIT, "in, event=0x%08x", event); nsp_dbg(NSP_DEBUG_INIT, "in, event=0x%08x", event);
@ -2062,51 +2113,6 @@ static int nsp_cs_event(event_t event,
#endif #endif
nsp_cs_config(link); nsp_cs_config(link);
break; break;
case CS_EVENT_PM_SUSPEND:
nsp_dbg(NSP_DEBUG_INIT, "event: suspend");
link->state |= DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_RESET_PHYSICAL:
/* Mark the device as stopped, to block IO until later */
nsp_dbg(NSP_DEBUG_INIT, "event: reset physical");
if (info->host != NULL) {
nsp_msg(KERN_INFO, "clear SDTR status");
data = (nsp_hw_data *)info->host->hostdata;
nsphw_init_sync(data);
}
info->stop = 1;
if (link->state & DEV_CONFIG) {
pcmcia_release_configuration(link->handle);
}
break;
case CS_EVENT_PM_RESUME:
nsp_dbg(NSP_DEBUG_INIT, "event: resume");
link->state &= ~DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_CARD_RESET:
nsp_dbg(NSP_DEBUG_INIT, "event: reset");
if (link->state & DEV_CONFIG) {
pcmcia_request_configuration(link->handle, &link->conf);
}
info->stop = 0;
if (info->host != NULL) {
nsp_msg(KERN_INFO, "reset host and bus");
data = (nsp_hw_data *)info->host->hostdata;
nsphw_init (data);
nsp_bus_reset(data);
}
break;
default: default:
nsp_dbg(NSP_DEBUG_INIT, "event: unknown"); nsp_dbg(NSP_DEBUG_INIT, "event: unknown");
break; break;
@ -2140,6 +2146,8 @@ static struct pcmcia_driver nsp_driver = {
.event = nsp_cs_event, .event = nsp_cs_event,
.detach = nsp_cs_detach, .detach = nsp_cs_detach,
.id_table = nsp_cs_ids, .id_table = nsp_cs_ids,
.suspend = nsp_cs_suspend,
.resume = nsp_cs_resume,
}; };
#endif #endif

View File

@ -349,6 +349,40 @@ static void qlogic_release(dev_link_t *link)
/*====================================================================*/ /*====================================================================*/
static int qlogic_suspend(struct pcmcia_device *dev)
{
dev_link_t *link = dev_to_instance(dev);
link->state |= DEV_SUSPEND;
if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle);
return 0;
}
static int qlogic_resume(struct pcmcia_device *dev)
{
dev_link_t *link = dev_to_instance(dev);
link->state &= ~DEV_SUSPEND;
if (link->state & DEV_CONFIG) {
scsi_info_t *info = link->priv;
pcmcia_request_configuration(link->handle, &link->conf);
if ((info->manf_id == MANFID_MACNICA) ||
(info->manf_id == MANFID_PIONEER) ||
(info->manf_id == 0x0098)) {
outb(0x80, link->io.BasePort1 + 0xd);
outb(0x24, link->io.BasePort1 + 0x9);
outb(0x04, link->io.BasePort1 + 0xd);
}
/* Ugggglllyyyy!!! */
qlogicfas408_bus_reset(NULL);
}
return 0;
}
static int qlogic_event(event_t event, int priority, event_callback_args_t * args) static int qlogic_event(event_t event, int priority, event_callback_args_t * args)
{ {
dev_link_t *link = args->client_data; dev_link_t *link = args->client_data;
@ -365,29 +399,6 @@ static int qlogic_event(event_t event, int priority, event_callback_args_t * arg
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
qlogic_config(link); qlogic_config(link);
break; break;
case CS_EVENT_PM_SUSPEND:
link->state |= DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_RESET_PHYSICAL:
if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle);
break;
case CS_EVENT_PM_RESUME:
link->state &= ~DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_CARD_RESET:
if (link->state & DEV_CONFIG) {
scsi_info_t *info = link->priv;
pcmcia_request_configuration(link->handle, &link->conf);
if ((info->manf_id == MANFID_MACNICA) || (info->manf_id == MANFID_PIONEER) || (info->manf_id == 0x0098)) {
outb(0x80, link->io.BasePort1 + 0xd);
outb(0x24, link->io.BasePort1 + 0x9);
outb(0x04, link->io.BasePort1 + 0xd);
}
/* Ugggglllyyyy!!! */
qlogicfas408_bus_reset(NULL);
}
break;
} }
return 0; return 0;
} /* qlogic_event */ } /* qlogic_event */
@ -423,6 +434,8 @@ static struct pcmcia_driver qlogic_cs_driver = {
.event = qlogic_event, .event = qlogic_event,
.detach = qlogic_detach, .detach = qlogic_detach,
.id_table = qlogic_ids, .id_table = qlogic_ids,
.suspend = qlogic_suspend,
.resume = qlogic_resume,
}; };
static int __init init_qlogic_cs(void) static int __init init_qlogic_cs(void)

View File

@ -872,11 +872,48 @@ cs_failed:
return; return;
} /* SYM53C500_config */ } /* SYM53C500_config */
static int sym53c500_suspend(struct pcmcia_device *dev)
{
dev_link_t *link = dev_to_instance(dev);
link->state |= DEV_SUSPEND;
if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle);
return 0;
}
static int sym53c500_resume(struct pcmcia_device *dev)
{
dev_link_t *link = dev_to_instance(dev);
struct scsi_info_t *info = link->priv;
link->state &= ~DEV_SUSPEND;
if (link->state & DEV_CONFIG) {
pcmcia_request_configuration(link->handle, &link->conf);
/* See earlier comment about manufacturer IDs. */
if ((info->manf_id == MANFID_MACNICA) ||
(info->manf_id == MANFID_PIONEER) ||
(info->manf_id == 0x0098)) {
outb(0x80, link->io.BasePort1 + 0xd);
outb(0x24, link->io.BasePort1 + 0x9);
outb(0x04, link->io.BasePort1 + 0xd);
}
/*
* If things don't work after a "resume",
* this is a good place to start looking.
*/
SYM53C500_int_host_reset(link->io.BasePort1);
}
return 0;
}
static int static int
SYM53C500_event(event_t event, int priority, event_callback_args_t *args) SYM53C500_event(event_t event, int priority, event_callback_args_t *args)
{ {
dev_link_t *link = args->client_data; dev_link_t *link = args->client_data;
struct scsi_info_t *info = link->priv;
DEBUG(1, "SYM53C500_event(0x%06x)\n", event); DEBUG(1, "SYM53C500_event(0x%06x)\n", event);
@ -890,34 +927,6 @@ SYM53C500_event(event_t event, int priority, event_callback_args_t *args)
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
SYM53C500_config(link); SYM53C500_config(link);
break; break;
case CS_EVENT_PM_SUSPEND:
link->state |= DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_RESET_PHYSICAL:
if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle);
break;
case CS_EVENT_PM_RESUME:
link->state &= ~DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_CARD_RESET:
if (link->state & DEV_CONFIG) {
pcmcia_request_configuration(link->handle, &link->conf);
/* See earlier comment about manufacturer IDs. */
if ((info->manf_id == MANFID_MACNICA) ||
(info->manf_id == MANFID_PIONEER) ||
(info->manf_id == 0x0098)) {
outb(0x80, link->io.BasePort1 + 0xd);
outb(0x24, link->io.BasePort1 + 0x9);
outb(0x04, link->io.BasePort1 + 0xd);
}
/*
* If things don't work after a "resume",
* this is a good place to start looking.
*/
SYM53C500_int_host_reset(link->io.BasePort1);
}
break;
} }
return 0; return 0;
} /* SYM53C500_event */ } /* SYM53C500_event */
@ -1012,6 +1021,8 @@ static struct pcmcia_driver sym53c500_cs_driver = {
.event = SYM53C500_event, .event = SYM53C500_event,
.detach = SYM53C500_detach, .detach = SYM53C500_detach,
.id_table = sym53c500_ids, .id_table = sym53c500_ids,
.suspend = sym53c500_suspend,
.resume = sym53c500_resume,
}; };
static int __init static int __init

View File

@ -159,8 +159,9 @@ static void serial_remove(dev_link_t *link)
} }
} }
static void serial_suspend(dev_link_t *link) static int serial_suspend(struct pcmcia_device *dev)
{ {
dev_link_t *link = dev_to_instance(dev);
link->state |= DEV_SUSPEND; link->state |= DEV_SUSPEND;
if (link->state & DEV_CONFIG) { if (link->state & DEV_CONFIG) {
@ -173,10 +174,13 @@ static void serial_suspend(dev_link_t *link)
if (!info->slave) if (!info->slave)
pcmcia_release_configuration(link->handle); pcmcia_release_configuration(link->handle);
} }
return 0;
} }
static void serial_resume(dev_link_t *link) static int serial_resume(struct pcmcia_device *dev)
{ {
dev_link_t *link = dev_to_instance(dev);
link->state &= ~DEV_SUSPEND; link->state &= ~DEV_SUSPEND;
if (DEV_OK(link)) { if (DEV_OK(link)) {
@ -189,6 +193,8 @@ static void serial_resume(dev_link_t *link)
for (i = 0; i < info->ndev; i++) for (i = 0; i < info->ndev; i++)
serial8250_resume_port(info->line[i]); serial8250_resume_port(info->line[i]);
} }
return 0;
} }
/*====================================================================== /*======================================================================
@ -731,7 +737,6 @@ static int
serial_event(event_t event, int priority, event_callback_args_t * args) serial_event(event_t event, int priority, event_callback_args_t * args)
{ {
dev_link_t *link = args->client_data; dev_link_t *link = args->client_data;
struct serial_info *info = link->priv;
DEBUG(1, "serial_event(0x%06x)\n", event); DEBUG(1, "serial_event(0x%06x)\n", event);
@ -744,24 +749,6 @@ serial_event(event_t event, int priority, event_callback_args_t * args)
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
serial_config(link); serial_config(link);
break; break;
case CS_EVENT_PM_SUSPEND:
serial_suspend(link);
break;
case CS_EVENT_RESET_PHYSICAL:
if ((link->state & DEV_CONFIG) && !info->slave)
pcmcia_release_configuration(link->handle);
break;
case CS_EVENT_PM_RESUME:
serial_resume(link);
break;
case CS_EVENT_CARD_RESET:
if (DEV_OK(link) && !info->slave)
pcmcia_request_configuration(link->handle, &link->conf);
break;
} }
return 0; return 0;
} }
@ -881,6 +868,8 @@ static struct pcmcia_driver serial_cs_driver = {
.event = serial_event, .event = serial_event,
.detach = serial_detach, .detach = serial_detach,
.id_table = serial_ids, .id_table = serial_ids,
.suspend = serial_suspend,
.resume = serial_resume,
}; };
static int __init init_serial_cs(void) static int __init init_serial_cs(void)

View File

@ -255,6 +255,28 @@ static void ixj_cs_release(dev_link_t *link)
link->state &= ~DEV_CONFIG; link->state &= ~DEV_CONFIG;
} }
static int ixj_suspend(struct pcmcia_device *dev)
{
dev_link_t *link = dev_to_instance(dev);
link->state |= DEV_SUSPEND;
if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle);
return 0;
}
static int ixj_resume(struct pcmcia_device *dev)
{
dev_link_t *link = dev_to_instance(dev);
link->state &= ~DEV_SUSPEND;
if (DEV_OK(link))
pcmcia_request_configuration(link->handle, &link->conf);
return 0;
}
static int ixj_event(event_t event, int priority, event_callback_args_t * args) static int ixj_event(event_t event, int priority, event_callback_args_t * args)
{ {
dev_link_t *link = args->client_data; dev_link_t *link = args->client_data;
@ -271,20 +293,6 @@ static int ixj_event(event_t event, int priority, event_callback_args_t * args)
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
ixj_config(link); ixj_config(link);
break; break;
case CS_EVENT_PM_SUSPEND:
link->state |= DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_RESET_PHYSICAL:
if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle);
break;
case CS_EVENT_PM_RESUME:
link->state &= ~DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_CARD_RESET:
if (DEV_OK(link))
pcmcia_request_configuration(link->handle, &link->conf);
break;
} }
return 0; return 0;
} }
@ -304,6 +312,8 @@ static struct pcmcia_driver ixj_driver = {
.event = ixj_event, .event = ixj_event,
.detach = ixj_detach, .detach = ixj_detach,
.id_table = ixj_ids, .id_table = ixj_ids,
.suspend = ixj_suspend,
.resume = ixj_resume,
}; };
static int __init ixj_pcmcia_init(void) static int __init ixj_pcmcia_init(void)

View File

@ -323,6 +323,28 @@ cs_failed:
} }
} }
static int sl811_suspend(struct pcmcia_device *dev)
{
dev_link_t *link = dev_to_instance(dev);
link->state |= DEV_SUSPEND;
if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle);
return 0;
}
static int sl811_resume(struct pcmcia_device *dev)
{
dev_link_t *link = dev_to_instance(dev);
link->state &= ~DEV_SUSPEND;
if (link->state & DEV_CONFIG)
pcmcia_request_configuration(link->handle, &link->conf);
return 0;
}
static int static int
sl811_cs_event(event_t event, int priority, event_callback_args_t *args) sl811_cs_event(event_t event, int priority, event_callback_args_t *args)
{ {
@ -341,23 +363,6 @@ sl811_cs_event(event_t event, int priority, event_callback_args_t *args)
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
sl811_cs_config(link); sl811_cs_config(link);
break; break;
case CS_EVENT_PM_SUSPEND:
link->state |= DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_RESET_PHYSICAL:
if (link->state & DEV_CONFIG)
pcmcia_release_configuration(link->handle);
break;
case CS_EVENT_PM_RESUME:
link->state &= ~DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_CARD_RESET:
if (link->state & DEV_CONFIG)
pcmcia_request_configuration(link->handle, &link->conf);
DBG(0, "reset sl811-hcd here?\n");
break;
} }
return 0; return 0;
} }
@ -417,6 +422,8 @@ static struct pcmcia_driver sl811_cs_driver = {
.event = sl811_cs_event, .event = sl811_cs_event,
.detach = sl811_cs_detach, .detach = sl811_cs_detach,
.id_table = sl811_ids, .id_table = sl811_ids,
.suspend = sl811_suspend,
.resume = sl811_resume,
}; };
/*====================================================================*/ /*====================================================================*/

View File

@ -137,6 +137,10 @@ struct pcmcia_driver {
int (*event) (event_t event, int priority, int (*event) (event_t event, int priority,
event_callback_args_t *); event_callback_args_t *);
void (*detach)(dev_link_t *); void (*detach)(dev_link_t *);
int (*suspend) (struct pcmcia_device *dev);
int (*resume) (struct pcmcia_device *dev);
struct module *owner; struct module *owner;
struct pcmcia_device_id *id_table; struct pcmcia_device_id *id_table;
struct device_driver drv; struct device_driver drv;
@ -193,6 +197,8 @@ struct pcmcia_device {
#define handle_to_pdev(handle) (handle) #define handle_to_pdev(handle) (handle)
#define handle_to_dev(handle) (handle->dev) #define handle_to_dev(handle) (handle->dev)
#define dev_to_instance(dev) (dev->instance)
/* error reporting */ /* error reporting */
void cs_error(client_handle_t handle, int func, int ret); void cs_error(client_handle_t handle, int func, int ret);