diff options
76 files changed, 2534 insertions, 5351 deletions
| diff --git a/Documentation/pcmcia/driver-changes.txt b/Documentation/pcmcia/driver-changes.txt index 403e7b4dcdd4..97420f08c786 100644 --- a/Documentation/pcmcia/driver-changes.txt +++ b/Documentation/pcmcia/driver-changes.txt @@ -1,5 +1,16 @@  This file details changes in 2.6 which affect PCMCIA card driver authors: +* Unify detach and REMOVAL event code, as well as attach and INSERTION +  code (as of 2.6.16) +       void (*remove)          (struct pcmcia_device *dev); +       int (*probe)            (struct pcmcia_device *dev); + +* 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)     The event handler is notified of all events, and must be initialized     as the event() callback in the driver's struct pcmcia_driver. diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index 4bafef83e79f..96370ec1d673 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c @@ -62,6 +62,7 @@ int dpm_runtime_suspend(struct device * dev, pm_message_t state)  	up(&dpm_sem);  	return error;  } +EXPORT_SYMBOL(dpm_runtime_suspend);  #if 0 diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c index f36c563d72c4..9888bc151755 100644 --- a/drivers/bluetooth/bluecard_cs.c +++ b/drivers/bluetooth/bluecard_cs.c @@ -87,14 +87,8 @@ typedef struct bluecard_info_t {  static void bluecard_config(dev_link_t *link);  static void bluecard_release(dev_link_t *link); -static int bluecard_event(event_t event, int priority, event_callback_args_t *args); -static dev_info_t dev_info = "bluecard_cs"; - -static dev_link_t *bluecard_attach(void); -static void bluecard_detach(dev_link_t *); - -static dev_link_t *dev_list = NULL; +static void bluecard_detach(struct pcmcia_device *p_dev);  /* Default baud rate: 57600, 115200, 230400 or 460800 */ @@ -862,17 +856,15 @@ static int bluecard_close(bluecard_info_t *info)  	return 0;  } -static dev_link_t *bluecard_attach(void) +static int bluecard_attach(struct pcmcia_device *p_dev)  {  	bluecard_info_t *info; -	client_reg_t client_reg;  	dev_link_t *link; -	int ret;  	/* Create new info device */  	info = kzalloc(sizeof(*info), GFP_KERNEL);  	if (!info) -		return NULL; +		return -ENOMEM;  	link = &info->link;  	link->priv = info; @@ -889,50 +881,24 @@ static dev_link_t *bluecard_attach(void)  	link->conf.Vcc = 50;  	link->conf.IntType = INT_MEMORY_AND_IO; -	/* Register with Card Services */ -	link->next = dev_list; -	dev_list = link; -	client_reg.dev_info = &dev_info; -	client_reg.Version = 0x0210; -	client_reg.event_callback_args.client_data = link; - -	ret = pcmcia_register_client(&link->handle, &client_reg); -	if (ret != CS_SUCCESS) { -		cs_error(link->handle, RegisterClient, ret); -		bluecard_detach(link); -		return NULL; -	} +	link->handle = p_dev; +	p_dev->instance = link; -	return link; +	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; +	bluecard_config(link); + +	return 0;  } -static void bluecard_detach(dev_link_t *link) +static void bluecard_detach(struct pcmcia_device *p_dev)  { +	dev_link_t *link = dev_to_instance(p_dev);  	bluecard_info_t *info = link->priv; -	dev_link_t **linkp; -	int ret; - -	/* Locate device structure */ -	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) -		if (*linkp == link) -			break; - -	if (*linkp == NULL) -		return;  	if (link->state & DEV_CONFIG)  		bluecard_release(link); -	if (link->handle) { -		ret = pcmcia_deregister_client(link->handle); -		if (ret != CS_SUCCESS) -			cs_error(link->handle, DeregisterClient, ret); -	} - -	/* Unlink device structure, free bits */ -	*linkp = link->next; -  	kfree(info);  } @@ -1045,39 +1011,24 @@ static void bluecard_release(dev_link_t *link)  	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); -static int bluecard_event(event_t event, int priority, event_callback_args_t *args) +	return 0; +} + +static int bluecard_resume(struct pcmcia_device *dev)  { -	dev_link_t *link = args->client_data; -	bluecard_info_t *info = link->priv; +	dev_link_t *link = dev_to_instance(dev); -	switch (event) { -	case CS_EVENT_CARD_REMOVAL: -		link->state &= ~DEV_PRESENT; -		if (link->state & DEV_CONFIG) { -			bluecard_close(info); -			bluecard_release(link); -		} -		break; -	case CS_EVENT_CARD_INSERTION: -		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; -		bluecard_config(link); -		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; -	} +	link->state &= ~DEV_SUSPEND; +	if (DEV_OK(link)) +		pcmcia_request_configuration(link->handle, &link->conf);  	return 0;  } @@ -1095,10 +1046,11 @@ static struct pcmcia_driver bluecard_driver = {  	.drv		= {  		.name	= "bluecard_cs",  	}, -	.attach		= bluecard_attach, -	.event		= bluecard_event, -	.detach		= bluecard_detach, +	.probe		= bluecard_attach, +	.remove		= bluecard_detach,  	.id_table	= bluecard_ids, +	.suspend	= bluecard_suspend, +	.resume		= bluecard_resume,  };  static int __init init_bluecard_cs(void) @@ -1110,7 +1062,6 @@ static int __init init_bluecard_cs(void)  static void __exit exit_bluecard_cs(void)  {  	pcmcia_unregister_driver(&bluecard_driver); -	BUG_ON(dev_list != NULL);  }  module_init(init_bluecard_cs); diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c index d2a0add19cc8..e522d19ad886 100644 --- a/drivers/bluetooth/bt3c_cs.c +++ b/drivers/bluetooth/bt3c_cs.c @@ -90,14 +90,8 @@ typedef struct bt3c_info_t {  static void bt3c_config(dev_link_t *link);  static void bt3c_release(dev_link_t *link); -static int bt3c_event(event_t event, int priority, event_callback_args_t *args); -static dev_info_t dev_info = "bt3c_cs"; - -static dev_link_t *bt3c_attach(void); -static void bt3c_detach(dev_link_t *); - -static dev_link_t *dev_list = NULL; +static void bt3c_detach(struct pcmcia_device *p_dev);  /* Transmit states  */ @@ -663,17 +657,15 @@ static int bt3c_close(bt3c_info_t *info)  	return 0;  } -static dev_link_t *bt3c_attach(void) +static int bt3c_attach(struct pcmcia_device *p_dev)  {  	bt3c_info_t *info; -	client_reg_t client_reg;  	dev_link_t *link; -	int ret;  	/* Create new info device */  	info = kzalloc(sizeof(*info), GFP_KERNEL);  	if (!info) -		return NULL; +		return -ENOMEM;  	link = &info->link;  	link->priv = info; @@ -690,50 +682,24 @@ static dev_link_t *bt3c_attach(void)  	link->conf.Vcc = 50;  	link->conf.IntType = INT_MEMORY_AND_IO; -	/* Register with Card Services */ -	link->next = dev_list; -	dev_list = link; -	client_reg.dev_info = &dev_info; -	client_reg.Version = 0x0210; -	client_reg.event_callback_args.client_data = link; - -	ret = pcmcia_register_client(&link->handle, &client_reg); -	if (ret != CS_SUCCESS) { -		cs_error(link->handle, RegisterClient, ret); -		bt3c_detach(link); -		return NULL; -	} +	link->handle = p_dev; +	p_dev->instance = link; -	return link; +	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; +	bt3c_config(link); + +	return 0;  } -static void bt3c_detach(dev_link_t *link) +static void bt3c_detach(struct pcmcia_device *p_dev)  { +	dev_link_t *link = dev_to_instance(p_dev);  	bt3c_info_t *info = link->priv; -	dev_link_t **linkp; -	int ret; - -	/* Locate device structure */ -	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) -		if (*linkp == link) -			break; - -	if (*linkp == NULL) -		return;  	if (link->state & DEV_CONFIG)  		bt3c_release(link); -	if (link->handle) { -		ret = pcmcia_deregister_client(link->handle); -		if (ret != CS_SUCCESS) -			cs_error(link->handle, DeregisterClient, ret); -	} - -	/* Unlink device structure, free bits */ -	*linkp = link->next; -  	kfree(info);  } @@ -891,43 +857,29 @@ static void bt3c_release(dev_link_t *link)  	link->state &= ~DEV_CONFIG;  } +static int bt3c_suspend(struct pcmcia_device *dev) +{ +	dev_link_t *link = dev_to_instance(dev); -static int bt3c_event(event_t event, int priority, event_callback_args_t *args) +	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 = args->client_data; -	bt3c_info_t *info = link->priv; +	dev_link_t *link = dev_to_instance(dev); -	switch (event) { -	case CS_EVENT_CARD_REMOVAL: -		link->state &= ~DEV_PRESENT; -		if (link->state & DEV_CONFIG) { -			bt3c_close(info); -			bt3c_release(link); -		} -		break; -	case CS_EVENT_CARD_INSERTION: -		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; -		bt3c_config(link); -		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; -	} +	link->state &= ~DEV_SUSPEND; +	if (DEV_OK(link)) +		pcmcia_request_configuration(link->handle, &link->conf);  	return 0;  } +  static struct pcmcia_device_id bt3c_ids[] = {  	PCMCIA_DEVICE_PROD_ID13("3COM", "Bluetooth PC Card", 0xefce0a31, 0xd4ce9b02),  	PCMCIA_DEVICE_NULL @@ -939,10 +891,11 @@ static struct pcmcia_driver bt3c_driver = {  	.drv		= {  		.name	= "bt3c_cs",  	}, -	.attach		= bt3c_attach, -	.event		= bt3c_event, -	.detach		= bt3c_detach, +	.probe		= bt3c_attach, +	.remove		= bt3c_detach,  	.id_table	= bt3c_ids, +	.suspend	= bt3c_suspend, +	.resume		= bt3c_resume,  };  static int __init init_bt3c_cs(void) @@ -954,7 +907,6 @@ static int __init init_bt3c_cs(void)  static void __exit exit_bt3c_cs(void)  {  	pcmcia_unregister_driver(&bt3c_driver); -	BUG_ON(dev_list != NULL);  }  module_init(init_bt3c_cs); diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c index 529a28a3209d..7b4bff4cfa2d 100644 --- a/drivers/bluetooth/btuart_cs.c +++ b/drivers/bluetooth/btuart_cs.c @@ -86,14 +86,8 @@ typedef struct btuart_info_t {  static void btuart_config(dev_link_t *link);  static void btuart_release(dev_link_t *link); -static int btuart_event(event_t event, int priority, event_callback_args_t *args); -static dev_info_t dev_info = "btuart_cs"; - -static dev_link_t *btuart_attach(void); -static void btuart_detach(dev_link_t *); - -static dev_link_t *dev_list = NULL; +static void btuart_detach(struct pcmcia_device *p_dev);  /* Maximum baud rate */ @@ -582,17 +576,15 @@ static int btuart_close(btuart_info_t *info)  	return 0;  } -static dev_link_t *btuart_attach(void) +static int btuart_attach(struct pcmcia_device *p_dev)  {  	btuart_info_t *info; -	client_reg_t client_reg;  	dev_link_t *link; -	int ret;  	/* Create new info device */  	info = kzalloc(sizeof(*info), GFP_KERNEL);  	if (!info) -		return NULL; +		return -ENOMEM;  	link = &info->link;  	link->priv = info; @@ -609,50 +601,24 @@ static dev_link_t *btuart_attach(void)  	link->conf.Vcc = 50;  	link->conf.IntType = INT_MEMORY_AND_IO; -	/* Register with Card Services */ -	link->next = dev_list; -	dev_list = link; -	client_reg.dev_info = &dev_info; -	client_reg.Version = 0x0210; -	client_reg.event_callback_args.client_data = link; - -	ret = pcmcia_register_client(&link->handle, &client_reg); -	if (ret != CS_SUCCESS) { -		cs_error(link->handle, RegisterClient, ret); -		btuart_detach(link); -		return NULL; -	} +	link->handle = p_dev; +	p_dev->instance = link; -	return link; +	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; +	btuart_config(link); + +	return 0;  } -static void btuart_detach(dev_link_t *link) +static void btuart_detach(struct pcmcia_device *p_dev)  { +	dev_link_t *link = dev_to_instance(p_dev);  	btuart_info_t *info = link->priv; -	dev_link_t **linkp; -	int ret; - -	/* Locate device structure */ -	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) -		if (*linkp == link) -			break; - -	if (*linkp == NULL) -		return;  	if (link->state & DEV_CONFIG)  		btuart_release(link); -	if (link->handle) { -		ret = pcmcia_deregister_client(link->handle); -		if (ret != CS_SUCCESS) -			cs_error(link->handle, DeregisterClient, ret); -	} - -	/* Unlink device structure, free bits */ -	*linkp = link->next; -  	kfree(info);  } @@ -811,43 +777,29 @@ static void btuart_release(dev_link_t *link)  	link->state &= ~DEV_CONFIG;  } +static int btuart_suspend(struct pcmcia_device *dev) +{ +	dev_link_t *link = dev_to_instance(dev); -static int btuart_event(event_t event, int priority, event_callback_args_t *args) +	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 = args->client_data; -	btuart_info_t *info = link->priv; +	dev_link_t *link = dev_to_instance(dev); -	switch (event) { -	case CS_EVENT_CARD_REMOVAL: -		link->state &= ~DEV_PRESENT; -		if (link->state & DEV_CONFIG) { -			btuart_close(info); -			btuart_release(link); -		} -		break; -	case CS_EVENT_CARD_INSERTION: -		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; -		btuart_config(link); -		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; -	} +	link->state &= ~DEV_SUSPEND; +	if (DEV_OK(link)) +		pcmcia_request_configuration(link->handle, &link->conf);  	return 0;  } +  static struct pcmcia_device_id btuart_ids[] = {  	/* don't use this driver. Use serial_cs + hci_uart instead */  	PCMCIA_DEVICE_NULL @@ -859,10 +811,11 @@ static struct pcmcia_driver btuart_driver = {  	.drv		= {  		.name	= "btuart_cs",  	}, -	.attach		= btuart_attach, -	.event		= btuart_event, -	.detach		= btuart_detach, +	.probe		= btuart_attach, +	.remove		= btuart_detach,  	.id_table	= btuart_ids, +	.suspend	= btuart_suspend, +	.resume		= btuart_resume,  };  static int __init init_btuart_cs(void) @@ -874,7 +827,6 @@ static int __init init_btuart_cs(void)  static void __exit exit_btuart_cs(void)  {  	pcmcia_unregister_driver(&btuart_driver); -	BUG_ON(dev_list != NULL);  }  module_init(init_btuart_cs); diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c index dec5980a1cd6..0449bc45ae5e 100644 --- a/drivers/bluetooth/dtl1_cs.c +++ b/drivers/bluetooth/dtl1_cs.c @@ -89,14 +89,8 @@ typedef struct dtl1_info_t {  static void dtl1_config(dev_link_t *link);  static void dtl1_release(dev_link_t *link); -static int dtl1_event(event_t event, int priority, event_callback_args_t *args); -static dev_info_t dev_info = "dtl1_cs"; - -static dev_link_t *dtl1_attach(void); -static void dtl1_detach(dev_link_t *); - -static dev_link_t *dev_list = NULL; +static void dtl1_detach(struct pcmcia_device *p_dev);  /* Transmit states  */ @@ -561,17 +555,15 @@ static int dtl1_close(dtl1_info_t *info)  	return 0;  } -static dev_link_t *dtl1_attach(void) +static int dtl1_attach(struct pcmcia_device *p_dev)  {  	dtl1_info_t *info; -	client_reg_t client_reg;  	dev_link_t *link; -	int ret;  	/* Create new info device */  	info = kzalloc(sizeof(*info), GFP_KERNEL);  	if (!info) -		return NULL; +		return -ENOMEM;  	link = &info->link;  	link->priv = info; @@ -588,50 +580,24 @@ static dev_link_t *dtl1_attach(void)  	link->conf.Vcc = 50;  	link->conf.IntType = INT_MEMORY_AND_IO; -	/* Register with Card Services */ -	link->next = dev_list; -	dev_list = link; -	client_reg.dev_info = &dev_info; -	client_reg.Version = 0x0210; -	client_reg.event_callback_args.client_data = link; - -	ret = pcmcia_register_client(&link->handle, &client_reg); -	if (ret != CS_SUCCESS) { -		cs_error(link->handle, RegisterClient, ret); -		dtl1_detach(link); -		return NULL; -	} +	link->handle = p_dev; +	p_dev->instance = link; -	return link; +	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; +	dtl1_config(link); + +	return 0;  } -static void dtl1_detach(dev_link_t *link) +static void dtl1_detach(struct pcmcia_device *p_dev)  { +	dev_link_t *link = dev_to_instance(p_dev);  	dtl1_info_t *info = link->priv; -	dev_link_t **linkp; -	int ret; - -	/* Locate device structure */ -	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) -		if (*linkp == link) -			break; - -	if (*linkp == NULL) -		return;  	if (link->state & DEV_CONFIG)  		dtl1_release(link); -	if (link->handle) { -		ret = pcmcia_deregister_client(link->handle); -		if (ret != CS_SUCCESS) -			cs_error(link->handle, DeregisterClient, ret); -	} - -	/* Unlink device structure, free bits */ -	*linkp = link->next; -  	kfree(info);  } @@ -763,46 +729,33 @@ static void dtl1_release(dev_link_t *link)  	link->state &= ~DEV_CONFIG;  } +static int dtl1_suspend(struct pcmcia_device *dev) +{ +	dev_link_t *link = dev_to_instance(dev); -static int dtl1_event(event_t event, int priority, event_callback_args_t *args) +	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 = args->client_data; -	dtl1_info_t *info = link->priv; +	dev_link_t *link = dev_to_instance(dev); -	switch (event) { -	case CS_EVENT_CARD_REMOVAL: -		link->state &= ~DEV_PRESENT; -		if (link->state & DEV_CONFIG) { -			dtl1_close(info); -			dtl1_release(link); -		} -		break; -	case CS_EVENT_CARD_INSERTION: -		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; -		dtl1_config(link); -		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; -	} +	link->state &= ~DEV_SUSPEND; +	if (DEV_OK(link)) +		pcmcia_request_configuration(link->handle, &link->conf);  	return 0;  } +  static struct pcmcia_device_id dtl1_ids[] = {  	PCMCIA_DEVICE_PROD_ID12("Nokia Mobile Phones", "DTL-1", 0xe1bfdd64, 0xe168480d),  	PCMCIA_DEVICE_PROD_ID12("Socket", "CF", 0xb38bcc2e, 0x44ebf863), +	PCMCIA_DEVICE_PROD_ID12("Socket", "CF+ Personal Network Card", 0xb38bcc2e, 0xe732bae3),  	PCMCIA_DEVICE_NULL  };  MODULE_DEVICE_TABLE(pcmcia, dtl1_ids); @@ -812,10 +765,11 @@ static struct pcmcia_driver dtl1_driver = {  	.drv		= {  		.name	= "dtl1_cs",  	}, -	.attach		= dtl1_attach, -	.event		= dtl1_event, -	.detach		= dtl1_detach, +	.probe		= dtl1_attach, +	.remove		= dtl1_detach,  	.id_table	= dtl1_ids, +	.suspend	= dtl1_suspend, +	.resume		= dtl1_resume,  };  static int __init init_dtl1_cs(void) @@ -827,7 +781,6 @@ static int __init init_dtl1_cs(void)  static void __exit exit_dtl1_cs(void)  {  	pcmcia_unregister_driver(&dtl1_driver); -	BUG_ON(dev_list != NULL);  }  module_init(init_dtl1_cs); diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c index 61681c9f3f72..649677b5dc36 100644 --- a/drivers/char/pcmcia/cm4000_cs.c +++ b/drivers/char/pcmcia/cm4000_cs.c @@ -66,7 +66,6 @@ static char *version = "cm4000_cs.c v2.4.0gm5 - All bugs added by Harald Welte";  #define	T_100MSEC	msecs_to_jiffies(100)  #define	T_500MSEC	msecs_to_jiffies(500) -static void cm4000_detach(dev_link_t *link);  static void cm4000_release(dev_link_t *link);  static int major;		/* major number we get from the kernel */ @@ -156,7 +155,6 @@ struct cm4000_dev {  		/*sbuf*/ 512*sizeof(char) - 			\  		/*queue*/ 4*sizeof(wait_queue_head_t)) -static dev_info_t dev_info = MODULE_NAME;  static dev_link_t *dev_table[CM4000_MAX_DEV];  /* This table doesn't use spaces after the comma between fields and thus @@ -1864,68 +1862,36 @@ cs_release:  	link->state &= ~DEV_CONFIG_PENDING;  } -static int cm4000_event(event_t event, int priority, -			event_callback_args_t *args) +static int cm4000_suspend(struct pcmcia_device *p_dev)  { -	dev_link_t *link; +	dev_link_t *link = dev_to_instance(p_dev);  	struct cm4000_dev *dev; -	int devno; -	link = args->client_data;  	dev = link->priv; -	DEBUGP(3, dev, "-> cm4000_event\n"); -	for (devno = 0; devno < CM4000_MAX_DEV; devno++) -		if (dev_table[devno] == link) -			break; +	link->state |= DEV_SUSPEND; +	if (link->state & DEV_CONFIG) +		pcmcia_release_configuration(link->handle); +	stop_monitor(dev); -	if (devno == CM4000_MAX_DEV) -		return CS_BAD_ADAPTER; +	return 0; +} -	switch (event) { -	case CS_EVENT_CARD_INSERTION: -		DEBUGP(5, dev, "CS_EVENT_CARD_INSERTION\n"); -		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; -		cm4000_config(link, devno); -		break; -	case CS_EVENT_CARD_REMOVAL: -		DEBUGP(5, dev, "CS_EVENT_CARD_REMOVAL\n"); -		link->state &= ~DEV_PRESENT; -		stop_monitor(dev); -		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: -		DEBUGP(5, dev, "unknown event %.2x\n", event); -		break; -	} -	DEBUGP(3, dev, "<- cm4000_event\n"); -	return CS_SUCCESS; +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) @@ -1935,11 +1901,10 @@ static void cm4000_release(dev_link_t *link)  	pcmcia_release_io(link->handle, &link->io);  } -static dev_link_t *cm4000_attach(void) +static int cm4000_attach(struct pcmcia_device *p_dev)  {  	struct cm4000_dev *dev;  	dev_link_t *link; -	client_reg_t client_reg;  	int i;  	for (i = 0; i < CM4000_MAX_DEV; i++) @@ -1948,76 +1913,55 @@ static dev_link_t *cm4000_attach(void)  	if (i == CM4000_MAX_DEV) {  		printk(KERN_NOTICE MODULE_NAME ": all devices in use\n"); -		return NULL; +		return -ENODEV;  	}  	/* create a new cm4000_cs device */  	dev = kzalloc(sizeof(struct cm4000_dev), GFP_KERNEL);  	if (dev == NULL) -		return NULL; +		return -ENOMEM;  	link = &dev->link;  	link->priv = dev;  	link->conf.IntType = INT_MEMORY_AND_IO;  	dev_table[i] = link; -	/* register with card services */ -	client_reg.dev_info = &dev_info; -	client_reg.EventMask = -	    CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL | -	    CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET | -	    CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME; -	client_reg.Version = 0x0210; -	client_reg.event_callback_args.client_data = link; - -	i = pcmcia_register_client(&link->handle, &client_reg); -	if (i) { -		cs_error(link->handle, RegisterClient, i); -		cm4000_detach(link); -		return NULL; -	} -  	init_waitqueue_head(&dev->devq);  	init_waitqueue_head(&dev->ioq);  	init_waitqueue_head(&dev->atrq);  	init_waitqueue_head(&dev->readq); -	return link; -} - -static void cm4000_detach_by_devno(int devno, dev_link_t * link) -{ -	struct cm4000_dev *dev = link->priv; - -	DEBUGP(3, dev, "-> detach_by_devno(devno=%d)\n", devno); - -	if (link->state & DEV_CONFIG) { -		DEBUGP(5, dev, "device still configured (try to release it)\n"); -		cm4000_release(link); -	} +	link->handle = p_dev; +	p_dev->instance = link; -	if (link->handle) { -		pcmcia_deregister_client(link->handle); -	} +	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; +	cm4000_config(link, i); -	dev_table[devno] = NULL; -	kfree(dev); -	return; +	return 0;  } -static void cm4000_detach(dev_link_t * link) +static void cm4000_detach(struct pcmcia_device *p_dev)  { -	int i; +	dev_link_t *link = dev_to_instance(p_dev); +	struct cm4000_dev *dev = link->priv; +	int devno;  	/* find device */ -	for (i = 0; i < CM4000_MAX_DEV; i++) -		if (dev_table[i] == link) +	for (devno = 0; devno < CM4000_MAX_DEV; devno++) +		if (dev_table[devno] == link)  			break; - -	if (i == CM4000_MAX_DEV) +	if (devno == CM4000_MAX_DEV)  		return; -	cm4000_detach_by_devno(i, link); +	link->state &= ~DEV_PRESENT; +	stop_monitor(dev); + +	if (link->state & DEV_CONFIG) + 		cm4000_release(link); + +	dev_table[devno] = NULL; + 	kfree(dev); +  	return;  } @@ -2042,9 +1986,10 @@ static struct pcmcia_driver cm4000_driver = {  	.drv	  = {  		.name = "cm4000_cs",  		}, -	.attach   = cm4000_attach, -	.detach   = cm4000_detach, -	.event	  = cm4000_event, +	.probe    = cm4000_attach, +	.remove   = cm4000_detach, +	.suspend  = cm4000_suspend, +	.resume   = cm4000_resume,  	.id_table = cm4000_ids,  }; @@ -2064,13 +2009,8 @@ static int __init cmm_init(void)  static void __exit cmm_exit(void)  { -	int i; -  	printk(KERN_INFO MODULE_NAME ": unloading\n");  	pcmcia_unregister_driver(&cm4000_driver); -	for (i = 0; i < CM4000_MAX_DEV; i++) -		if (dev_table[i]) -			cm4000_detach_by_devno(i, dev_table[i]);  	unregister_chrdev(major, DEVICE_NAME);  }; diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c index 4c698d908ffa..46eb371bf17e 100644 --- a/drivers/char/pcmcia/cm4040_cs.c +++ b/drivers/char/pcmcia/cm4040_cs.c @@ -65,7 +65,6 @@ static char *version =  #define POLL_PERIOD 				msecs_to_jiffies(10)  static void reader_release(dev_link_t *link); -static void reader_detach(dev_link_t *link);  static int major; @@ -86,7 +85,6 @@ struct reader_dev {  	struct timer_list 	poll_timer;  }; -static dev_info_t dev_info = MODULE_NAME;  static dev_link_t *dev_table[CM_MAX_DEV];  #ifndef PCMCIA_DEBUG @@ -629,65 +627,26 @@ cs_release:  	link->state &= ~DEV_CONFIG_PENDING;  } -static int reader_event(event_t event, int priority, -			event_callback_args_t *args) +static int reader_suspend(struct pcmcia_device *p_dev)  { -	dev_link_t *link; -	struct reader_dev *dev; -	int devno; +	dev_link_t *link = dev_to_instance(p_dev); -	link = args->client_data; -	dev = link->priv; -	DEBUGP(3, dev, "-> reader_event\n"); -	for (devno = 0; devno < CM_MAX_DEV; devno++) { -		if (dev_table[devno] == link) -			break; -	} -	if (devno == CM_MAX_DEV) -		return CS_BAD_ADAPTER; +	link->state |= DEV_SUSPEND; +	if (link->state & DEV_CONFIG) +		pcmcia_release_configuration(link->handle); -	switch (event) { -		case CS_EVENT_CARD_INSERTION: -			DEBUGP(5, dev, "CS_EVENT_CARD_INSERTION\n"); -			link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; -			reader_config(link, devno); -			break; -		case CS_EVENT_CARD_REMOVAL: -			DEBUGP(5, dev, "CS_EVENT_CARD_REMOVAL\n"); -			link->state &= ~DEV_PRESENT; -			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: -			DEBUGP(5, dev, "reader_event: unknown event %.2x\n", -			       event); -			break; -	} -	DEBUGP(3, dev, "<- reader_event\n"); -	return CS_SUCCESS; +	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) @@ -697,11 +656,10 @@ static void reader_release(dev_link_t *link)  	pcmcia_release_io(link->handle, &link->io);  } -static dev_link_t *reader_attach(void) +static int reader_attach(struct pcmcia_device *p_dev)  {  	struct reader_dev *dev;  	dev_link_t *link; -	client_reg_t client_reg;  	int i;  	for (i = 0; i < CM_MAX_DEV; i++) { @@ -710,11 +668,11 @@ static dev_link_t *reader_attach(void)  	}  	if (i == CM_MAX_DEV) -		return NULL; +		return -ENODEV;  	dev = kzalloc(sizeof(struct reader_dev), GFP_KERNEL);  	if (dev == NULL) -		return NULL; +		return -ENOMEM;  	dev->timeout = CCID_DRIVER_MINIMUM_TIMEOUT;  	dev->buffer_status = 0; @@ -725,20 +683,6 @@ static dev_link_t *reader_attach(void)  	link->conf.IntType = INT_MEMORY_AND_IO;  	dev_table[i] = link; -	client_reg.dev_info = &dev_info; -	client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE; -	client_reg.EventMask= -		CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL | -		CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET | -		CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME; -	client_reg.Version = 0x0210; -	client_reg.event_callback_args.client_data = link; -	i = pcmcia_register_client(&link->handle, &client_reg); -	if (i) { -		cs_error(link->handle, RegisterClient, i); -		reader_detach(link); -		return NULL; -	}  	init_waitqueue_head(&dev->devq);  	init_waitqueue_head(&dev->poll_wait);  	init_waitqueue_head(&dev->read_wait); @@ -746,39 +690,37 @@ static dev_link_t *reader_attach(void)  	init_timer(&dev->poll_timer);  	dev->poll_timer.function = &cm4040_do_poll; -	return link; -} - -static void reader_detach_by_devno(int devno, dev_link_t *link) -{ -	struct reader_dev *dev = link->priv; +	link->handle = p_dev; +	p_dev->instance = link; -	if (link->state & DEV_CONFIG) { -		DEBUGP(5, dev, "device still configured (try to release it)\n"); -		reader_release(link); -	} +	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; +	reader_config(link, i); -	pcmcia_deregister_client(link->handle); -	dev_table[devno] = NULL; -	DEBUGP(5, dev, "freeing dev=%p\n", dev); -	cm4040_stop_poll(dev); -	kfree(dev); -	return; +	return 0;  } -static void reader_detach(dev_link_t *link) +static void reader_detach(struct pcmcia_device *p_dev)  { -	int i; +	dev_link_t *link = dev_to_instance(p_dev); +	struct reader_dev *dev = link->priv; +	int devno;  	/* find device */ -	for (i = 0; i < CM_MAX_DEV; i++) { -		if (dev_table[i] == link) +	for (devno = 0; devno < CM_MAX_DEV; devno++) { +		if (dev_table[devno] == link)  			break;  	} -	if (i == CM_MAX_DEV) +	if (devno == CM_MAX_DEV)  		return; -	reader_detach_by_devno(i, link); +	link->state &= ~DEV_PRESENT; + +	if (link->state & DEV_CONFIG) +		reader_release(link); + +	dev_table[devno] = NULL; +	kfree(dev); +  	return;  } @@ -804,9 +746,10 @@ static struct pcmcia_driver reader_driver = {    	.drv		= {  		.name	= "cm4040_cs",  	}, -	.attach		= reader_attach, -	.detach		= reader_detach, -	.event		= reader_event, +	.probe		= reader_attach, +	.remove		= reader_detach, +	.suspend	= reader_suspend, +	.resume		= reader_resume,  	.id_table	= cm4040_ids,  }; @@ -825,14 +768,8 @@ static int __init cm4040_init(void)  static void __exit cm4040_exit(void)  { -	int i; -  	printk(KERN_INFO MODULE_NAME ": unloading\n");  	pcmcia_unregister_driver(&reader_driver); -	for (i = 0; i < CM_MAX_DEV; i++) { -		if (dev_table[i]) -			reader_detach_by_devno(i, dev_table[i]); -	}  	unregister_chrdev(major, DEVICE_NAME);  } diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index 2c326ea53421..cf45b100eff1 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c @@ -486,13 +486,7 @@ static void mgslpc_wait_until_sent(struct tty_struct *tty, int timeout);  static void mgslpc_config(dev_link_t *link);  static void mgslpc_release(u_long arg); -static int  mgslpc_event(event_t event, int priority, -			 event_callback_args_t *args); -static dev_link_t *mgslpc_attach(void); -static void mgslpc_detach(dev_link_t *); - -static dev_info_t dev_info = "synclink_cs"; -static dev_link_t *dev_list = NULL; +static void mgslpc_detach(struct pcmcia_device *p_dev);  /*   * 1st function defined in .text section. Calling this function in @@ -539,12 +533,10 @@ static void ldisc_receive_buf(struct tty_struct *tty,  	}  } -static dev_link_t *mgslpc_attach(void) +static int mgslpc_attach(struct pcmcia_device *p_dev)  {      MGSLPC_INFO *info;      dev_link_t *link; -    client_reg_t client_reg; -    int ret;      if (debug_level >= DEBUG_LEVEL_INFO)  	    printk("mgslpc_attach\n"); @@ -552,7 +544,7 @@ static dev_link_t *mgslpc_attach(void)      info = (MGSLPC_INFO *)kmalloc(sizeof(MGSLPC_INFO), GFP_KERNEL);      if (!info) {  	    printk("Error can't allocate device instance data\n"); -	    return NULL; +	    return -ENOMEM;      }      memset(info, 0, sizeof(MGSLPC_INFO)); @@ -587,24 +579,15 @@ static dev_link_t *mgslpc_attach(void)      link->conf.Vcc = 50;      link->conf.IntType = INT_MEMORY_AND_IO; -    /* Register with Card Services */ -    link->next = dev_list; -    dev_list = link; - -    client_reg.dev_info = &dev_info; -    client_reg.Version = 0x0210; -    client_reg.event_callback_args.client_data = link; +    link->handle = p_dev; +    p_dev->instance = link; -    ret = pcmcia_register_client(&link->handle, &client_reg); -    if (ret != CS_SUCCESS) { -	    cs_error(link->handle, RegisterClient, ret); -	    mgslpc_detach(link); -	    return NULL; -    } +    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; +    mgslpc_config(link);      mgslpc_add_device(info); -    return link; +    return 0;  }  /* Card has been inserted. @@ -736,85 +719,50 @@ static void mgslpc_release(u_long arg)  	    pcmcia_release_io(link->handle, &link->io);      if (link->irq.AssignedIRQ)  	    pcmcia_release_irq(link->handle, &link->irq); -    if (link->state & DEV_STALE_LINK) -	    mgslpc_detach(link);  } -static void mgslpc_detach(dev_link_t *link) +static void mgslpc_detach(struct pcmcia_device *p_dev)  { -    dev_link_t **linkp; +    dev_link_t *link = dev_to_instance(p_dev);      if (debug_level >= DEBUG_LEVEL_INFO)  	    printk("mgslpc_detach(0x%p)\n", link); -     -    /* find device */ -    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) -	    if (*linkp == link) break; -    if (*linkp == NULL) -	    return;      if (link->state & DEV_CONFIG) { -	    /* device is configured/active, mark it so when -	     * release() is called a proper detach() occurs. -	     */ -	    if (debug_level >= DEBUG_LEVEL_INFO) -		    printk(KERN_DEBUG "synclinkpc: detach postponed, '%s' " -			   "still locked\n", link->dev->dev_name); -	    link->state |= DEV_STALE_LINK; -	    return; +	    ((MGSLPC_INFO *)link->priv)->stop = 1; +	    mgslpc_release((u_long)link);      } -    /* Break the link with Card Services */ -    if (link->handle) -	    pcmcia_deregister_client(link->handle); -     -    /* Unlink device structure, and free it */ -    *linkp = link->next;      mgslpc_remove_device((MGSLPC_INFO *)link->priv);  } -static int mgslpc_event(event_t event, int priority, -			event_callback_args_t *args) +static int mgslpc_suspend(struct pcmcia_device *dev)  { -    dev_link_t *link = args->client_data; -    MGSLPC_INFO *info = link->priv; -     -    if (debug_level >= DEBUG_LEVEL_INFO) -	    printk("mgslpc_event(0x%06x)\n", event); -     -    switch (event) { -    case CS_EVENT_CARD_REMOVAL: -	    link->state &= ~DEV_PRESENT; -	    if (link->state & DEV_CONFIG) { -		    ((MGSLPC_INFO *)link->priv)->stop = 1; -		    mgslpc_release((u_long)link); -	    } -	    break; -    case CS_EVENT_CARD_INSERTION: -	    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; -	    mgslpc_config(link); -	    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; +	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 inline int mgslpc_paranoia_check(MGSLPC_INFO *info,  					char *name, const char *routine)  { @@ -3091,10 +3039,11 @@ static struct pcmcia_driver mgslpc_driver = {  	.drv		= {  		.name	= "synclink_cs",  	}, -	.attach		= mgslpc_attach, -	.event		= mgslpc_event, -	.detach		= mgslpc_detach, +	.probe		= mgslpc_attach, +	.remove		= mgslpc_detach,  	.id_table	= mgslpc_ids, +	.suspend	= mgslpc_suspend, +	.resume		= mgslpc_resume,  };  static struct tty_operations mgslpc_ops = { @@ -3138,7 +3087,6 @@ static void synclink_cs_cleanup(void)  	}  	pcmcia_unregister_driver(&mgslpc_driver); -	BUG_ON(dev_list != NULL);  }  static int __init synclink_cs_init(void) diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c index ef79805218e4..4c2af9020905 100644 --- a/drivers/ide/legacy/ide-cs.c +++ b/drivers/ide/legacy/ide-cs.c @@ -88,15 +88,12 @@ typedef struct ide_info_t {  } ide_info_t;  static void ide_release(dev_link_t *); -static int ide_event(event_t event, int priority, -		     event_callback_args_t *args); +static void ide_config(dev_link_t *); + +static void ide_detach(struct pcmcia_device *p_dev); -static dev_info_t dev_info = "ide-cs"; -static dev_link_t *ide_attach(void); -static void ide_detach(dev_link_t *); -static dev_link_t *dev_list = NULL;  /*====================================================================== @@ -106,18 +103,17 @@ static dev_link_t *dev_list = NULL;  ======================================================================*/ -static dev_link_t *ide_attach(void) +static int ide_attach(struct pcmcia_device *p_dev)  {      ide_info_t *info;      dev_link_t *link; -    client_reg_t client_reg; -    int ret; -     +      DEBUG(0, "ide_attach()\n");      /* Create new ide device */      info = kzalloc(sizeof(*info), GFP_KERNEL); -    if (!info) return NULL; +    if (!info) +	return -ENOMEM;      link = &info->link; link->priv = info;      link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; @@ -128,21 +124,14 @@ static dev_link_t *ide_attach(void)      link->conf.Attributes = CONF_ENABLE_IRQ;      link->conf.Vcc = 50;      link->conf.IntType = INT_MEMORY_AND_IO; -     -    /* Register with Card Services */ -    link->next = dev_list; -    dev_list = link; -    client_reg.dev_info = &dev_info; -    client_reg.Version = 0x0210; -    client_reg.event_callback_args.client_data = link; -    ret = pcmcia_register_client(&link->handle, &client_reg); -    if (ret != CS_SUCCESS) { -	cs_error(link->handle, RegisterClient, ret); -	ide_detach(link); -	return NULL; -    } -     -    return link; + +    link->handle = p_dev; +    p_dev->instance = link; + +    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; +    ide_config(link); + +    return 0;  } /* ide_attach */  /*====================================================================== @@ -154,32 +143,16 @@ static dev_link_t *ide_attach(void)  ======================================================================*/ -static void ide_detach(dev_link_t *link) +static void ide_detach(struct pcmcia_device *p_dev)  { -    dev_link_t **linkp; -    int ret; +    dev_link_t *link = dev_to_instance(p_dev);      DEBUG(0, "ide_detach(0x%p)\n", link); -     -    /* Locate device structure */ -    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) -	if (*linkp == link) break; -    if (*linkp == NULL) -	return;      if (link->state & DEV_CONFIG)  	ide_release(link); -     -    if (link->handle) { -	ret = pcmcia_deregister_client(link->handle); -	if (ret != CS_SUCCESS) -	    cs_error(link->handle, DeregisterClient, ret); -    } -     -    /* Unlink, free device structure */ -    *linkp = link->next; +      kfree(link->priv); -      } /* ide_detach */  static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq, struct pcmcia_device *handle) @@ -406,6 +379,28 @@ void ide_release(dev_link_t *link)  } /* 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 @@ -415,48 +410,15 @@ void ide_release(dev_link_t *link)  ======================================================================*/ -int ide_event(event_t event, int priority, -	      event_callback_args_t *args) -{ -    dev_link_t *link = args->client_data; - -    DEBUG(1, "ide_event(0x%06x)\n", event); -     -    switch (event) { -    case CS_EVENT_CARD_REMOVAL: -	link->state &= ~DEV_PRESENT; -	if (link->state & DEV_CONFIG) -		ide_release(link); -	break; -    case CS_EVENT_CARD_INSERTION: -	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; -	ide_config(link); -	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; -} /* ide_event */ -  static struct pcmcia_device_id ide_ids[] = {  	PCMCIA_DEVICE_FUNC_ID(4), +	PCMCIA_DEVICE_MANF_CARD(0x0007, 0x0000),	/* Hitachi */  	PCMCIA_DEVICE_MANF_CARD(0x0032, 0x0704),  	PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401),  	PCMCIA_DEVICE_MANF_CARD(0x0098, 0x0000),	/* Toshiba */  	PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d),  	PCMCIA_DEVICE_MANF_CARD(0x00ce, 0x0000),	/* Samsung */ + 	PCMCIA_DEVICE_MANF_CARD(0x0319, 0x0000),	/* Hitachi */  	PCMCIA_DEVICE_MANF_CARD(0x2080, 0x0001),  	PCMCIA_DEVICE_MANF_CARD(0x4e01, 0x0200),	/* Lexar */  	PCMCIA_DEVICE_PROD_ID123("Caravelle", "PSC-IDE ", "PSC000", 0x8c36137c, 0xd0693ab8, 0x2768a9f0), @@ -471,6 +433,8 @@ static struct pcmcia_device_id ide_ids[] = {  	PCMCIA_DEVICE_PROD_ID12("EXP   ", "CD-ROM", 0x0a5c52fd, 0x66536591),  	PCMCIA_DEVICE_PROD_ID12("EXP   ", "PnPIDE", 0x0a5c52fd, 0x0c694728),  	PCMCIA_DEVICE_PROD_ID12("FREECOM", "PCCARD-IDE", 0x5714cbf7, 0x48e0ab8e), +	PCMCIA_DEVICE_PROD_ID12("HITACHI", "FLASH", 0xf4f43949, 0x9eb86aae), +	PCMCIA_DEVICE_PROD_ID12("HITACHI", "microdrive", 0xf4f43949, 0xa6d76178),  	PCMCIA_DEVICE_PROD_ID12("IBM", "IBM17JSSFP20", 0xb569a6e5, 0xf2508753),  	PCMCIA_DEVICE_PROD_ID12("IO DATA", "CBIDE2      ", 0x547e66dc, 0x8671043b),  	PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCIDE", 0x547e66dc, 0x5c5ab149), @@ -494,10 +458,11 @@ static struct pcmcia_driver ide_cs_driver = {  	.drv		= {  		.name	= "ide-cs",  	}, -	.attach		= ide_attach, -	.event		= ide_event, -	.detach		= ide_detach, +	.probe		= ide_attach, +	.remove		= ide_detach,  	.id_table       = ide_ids, +	.suspend	= ide_suspend, +	.resume		= ide_resume,  };  static int __init init_ide_cs(void) @@ -508,7 +473,6 @@ static int __init init_ide_cs(void)  static void __exit exit_ide_cs(void)  {  	pcmcia_unregister_driver(&ide_cs_driver); -	BUG_ON(dev_list != NULL);  }  late_initcall(init_ide_cs); diff --git a/drivers/isdn/hardware/avm/avm_cs.c b/drivers/isdn/hardware/avm/avm_cs.c index 27391c32f3eb..2a2b03ff096b 100644 --- a/drivers/isdn/hardware/avm/avm_cs.c +++ b/drivers/isdn/hardware/avm/avm_cs.c @@ -53,8 +53,6 @@ MODULE_LICENSE("GPL");  static void avmcs_config(dev_link_t *link);  static void avmcs_release(dev_link_t *link); -static int avmcs_event(event_t event, int priority, -			  event_callback_args_t *args);  /*     The attach() and detach() entry points are used to create and destroy @@ -62,16 +60,7 @@ static int avmcs_event(event_t event, int priority,     needed to manage one actual PCMCIA card.  */ -static dev_link_t *avmcs_attach(void); -static void avmcs_detach(dev_link_t *); - -/* -   The dev_info variable is the "key" that is used to match up this -   device driver with appropriate cards, through the card configuration -   database. -*/ - -static dev_info_t dev_info = "avm_cs"; +static void avmcs_detach(struct pcmcia_device *p_dev);  /*     A linked list of "instances" of the skeleton device.  Each actual @@ -83,15 +72,7 @@ static dev_info_t dev_info = "avm_cs";     device numbers are used to derive the corresponding array index.  */ -static dev_link_t *dev_list = NULL; -  /* -   A dev_link_t structure has fields for most things that are needed -   to keep track of a socket, but there will usually be some device -   specific information that also needs to be kept track of.  The -   'priv' pointer in a dev_link_t structure can be used to point to -   a device-specific private data structure, like this. -     A driver needs to provide a dev_node_t structure for each device     on a card.  In some cases, there is only one device per card (for     example, ethernet cards, modems).  In other cases, there may be @@ -118,13 +99,11 @@ typedef struct local_info_t {  ======================================================================*/ -static dev_link_t *avmcs_attach(void) +static int avmcs_attach(struct pcmcia_device *p_dev)  { -    client_reg_t client_reg;      dev_link_t *link;      local_info_t *local; -    int ret; -     +      /* Initialize the dev_link_t structure */      link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);      if (!link) @@ -155,25 +134,19 @@ static dev_link_t *avmcs_attach(void)          goto err_kfree;      memset(local, 0, sizeof(local_info_t));      link->priv = local; -     -    /* Register with Card Services */ -    link->next = dev_list; -    dev_list = link; -    client_reg.dev_info = &dev_info; -    client_reg.Version = 0x0210; -    client_reg.event_callback_args.client_data = link; -    ret = pcmcia_register_client(&link->handle, &client_reg); -    if (ret != 0) { -	cs_error(link->handle, RegisterClient, ret); -	avmcs_detach(link); -	goto err; -    } -    return link; + +    link->handle = p_dev; +    p_dev->instance = link; + +    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; +    avmcs_config(link); + +    return 0;   err_kfree:      kfree(link);   err: -    return NULL; +    return -EINVAL;  } /* avmcs_attach */  /*====================================================================== @@ -185,33 +158,13 @@ static dev_link_t *avmcs_attach(void)  ======================================================================*/ -static void avmcs_detach(dev_link_t *link) +static void avmcs_detach(struct pcmcia_device *p_dev)  { -    dev_link_t **linkp; - -    /* Locate device structure */ -    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) -	if (*linkp == link) break; -    if (*linkp == NULL) -	return; +    dev_link_t *link = dev_to_instance(p_dev); -    /* -       If the device is currently configured and active, we won't -       actually delete it yet.  Instead, it is marked so that when -       the release() function is called, that will trigger a proper -       detach(). -    */ -    if (link->state & DEV_CONFIG) { -	link->state |= DEV_STALE_LINK; -	return; -    } +    if (link->state & DEV_CONFIG) +	avmcs_release(link); -    /* Break the link with Card Services */ -    if (link->handle) -	pcmcia_deregister_client(link->handle); -     -    /* Unlink device structure, free pieces */ -    *linkp = link->next;      kfree(link->priv);      kfree(link);  } /* avmcs_detach */ @@ -424,12 +377,30 @@ static void avmcs_release(dev_link_t *link)      pcmcia_release_io(link->handle, &link->io);      pcmcia_release_irq(link->handle, &link->irq);      link->state &= ~DEV_CONFIG; -     -    if (link->state & DEV_STALE_LINK) -	avmcs_detach(link); -      } /* 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 @@ -444,38 +415,6 @@ static void avmcs_release(dev_link_t *link)  ======================================================================*/ -static int avmcs_event(event_t event, int priority, -			  event_callback_args_t *args) -{ -    dev_link_t *link = args->client_data; - -    switch (event) { -    case CS_EVENT_CARD_REMOVAL: -	link->state &= ~DEV_PRESENT; -	if (link->state & DEV_CONFIG) -		avmcs_release(link); -	break; -    case CS_EVENT_CARD_INSERTION: -	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; -	avmcs_config(link); -	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; -} /* avmcs_event */  static struct pcmcia_device_id avmcs_ids[] = {  	PCMCIA_DEVICE_PROD_ID12("AVM", "ISDN-Controller B1", 0x95d42008, 0x845dc335), @@ -490,10 +429,11 @@ static struct pcmcia_driver avmcs_driver = {  	.drv	= {  		.name	= "avm_cs",  	}, -	.attach	= avmcs_attach, -	.event	= avmcs_event, -	.detach	= avmcs_detach, +	.probe = avmcs_attach, +	.remove	= avmcs_detach,  	.id_table = avmcs_ids, +	.suspend= avmcs_suspend, +	.resume = avmcs_resume,  };  static int __init avmcs_init(void) @@ -504,7 +444,6 @@ static int __init avmcs_init(void)  static void __exit avmcs_exit(void)  {  	pcmcia_unregister_driver(&avmcs_driver); -	BUG_ON(dev_list != NULL);  }  module_init(avmcs_init); diff --git a/drivers/isdn/hisax/avma1_cs.c b/drivers/isdn/hisax/avma1_cs.c index 5f5a5ae740d2..969da40c4248 100644 --- a/drivers/isdn/hisax/avma1_cs.c +++ b/drivers/isdn/hisax/avma1_cs.c @@ -69,8 +69,6 @@ module_param(isdnprot, int, 0);  static void avma1cs_config(dev_link_t *link);  static void avma1cs_release(dev_link_t *link); -static int avma1cs_event(event_t event, int priority, -			  event_callback_args_t *args);  /*     The attach() and detach() entry points are used to create and destroy @@ -78,16 +76,8 @@ static int avma1cs_event(event_t event, int priority,     needed to manage one actual PCMCIA card.  */ -static dev_link_t *avma1cs_attach(void); -static void avma1cs_detach(dev_link_t *); +static void avma1cs_detach(struct pcmcia_device *p_dev); -/* -   The dev_info variable is the "key" that is used to match up this -   device driver with appropriate cards, through the card configuration -   database. -*/ - -static dev_info_t dev_info = "avma1_cs";  /*     A linked list of "instances" of the skeleton device.  Each actual @@ -99,15 +89,7 @@ static dev_info_t dev_info = "avma1_cs";     device numbers are used to derive the corresponding array index.  */ -static dev_link_t *dev_list = NULL; -  /* -   A dev_link_t structure has fields for most things that are needed -   to keep track of a socket, but there will usually be some device -   specific information that also needs to be kept track of.  The -   'priv' pointer in a dev_link_t structure can be used to point to -   a device-specific private data structure, like this. -     A driver needs to provide a dev_node_t structure for each device     on a card.  In some cases, there is only one device per card (for     example, ethernet cards, modems).  In other cases, there may be @@ -134,26 +116,24 @@ typedef struct local_info_t {  ======================================================================*/ -static dev_link_t *avma1cs_attach(void) +static int avma1cs_attach(struct pcmcia_device *p_dev)  { -    client_reg_t client_reg;      dev_link_t *link;      local_info_t *local; -    int ret; -     +      DEBUG(0, "avma1cs_attach()\n");      /* Initialize the dev_link_t structure */      link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);      if (!link) -	return NULL; +	return -ENOMEM;      memset(link, 0, sizeof(struct dev_link_t));      /* Allocate space for private device-specific data */      local = kmalloc(sizeof(local_info_t), GFP_KERNEL);      if (!local) {  	kfree(link); -	return NULL; +	return -ENOMEM;      }      memset(local, 0, sizeof(local_info_t));      link->priv = local; @@ -178,20 +158,13 @@ static dev_link_t *avma1cs_attach(void)      link->conf.ConfigIndex = 1;      link->conf.Present = PRESENT_OPTION; -    /* Register with Card Services */ -    link->next = dev_list; -    dev_list = link; -    client_reg.dev_info = &dev_info; -    client_reg.Version = 0x0210; -    client_reg.event_callback_args.client_data = link; -    ret = pcmcia_register_client(&link->handle, &client_reg); -    if (ret != 0) { -	cs_error(link->handle, RegisterClient, ret); -	avma1cs_detach(link); -	return NULL; -    } +    link->handle = p_dev; +    p_dev->instance = link; -    return link; +    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; +    avma1cs_config(link); + +    return 0;  } /* avma1cs_attach */  /*====================================================================== @@ -203,42 +176,17 @@ static dev_link_t *avma1cs_attach(void)  ======================================================================*/ -static void avma1cs_detach(dev_link_t *link) +static void avma1cs_detach(struct pcmcia_device *p_dev)  { -    dev_link_t **linkp; +    dev_link_t *link = dev_to_instance(p_dev);      DEBUG(0, "avma1cs_detach(0x%p)\n", link); -     -    /* Locate device structure */ -    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) -	if (*linkp == link) break; -    if (*linkp == NULL) -	return; -    /* -       If the device is currently configured and active, we won't -       actually delete it yet.  Instead, it is marked so that when -       the release() function is called, that will trigger a proper -       detach(). -    */ -    if (link->state & DEV_CONFIG) { -#ifdef PCMCIA_DEBUG -	printk(KERN_DEBUG "avma1_cs: detach postponed, '%s' " -	       "still locked\n", link->dev->dev_name); -#endif -	link->state |= DEV_STALE_LINK; -	return; -    } +    if (link->state & DEV_CONFIG) +	    avma1cs_release(link); -    /* Break the link with Card Services */ -    if (link->handle) -    	pcmcia_deregister_client(link->handle); -     -    /* Unlink device structure, free pieces */ -    *linkp = link->next;      kfree(link->priv);      kfree(link); -      } /* avma1cs_detach */  /*====================================================================== @@ -440,58 +388,30 @@ static void avma1cs_release(dev_link_t *link)      pcmcia_release_io(link->handle, &link->io);      pcmcia_release_irq(link->handle, &link->irq);      link->state &= ~DEV_CONFIG; -     -    if (link->state & DEV_STALE_LINK) -	avma1cs_detach(link);  } /* avma1cs_release */ -/*====================================================================== +static int avma1cs_suspend(struct pcmcia_device *dev) +{ +	dev_link_t *link = dev_to_instance(dev); -    The card status event handler.  Mostly, this schedules other -    stuff to run after an event is received.  A CARD_REMOVAL event -    also sets some flags to discourage the net drivers from trying -    to talk to the card any more. +	link->state |= DEV_SUSPEND; +	if (link->state & DEV_CONFIG) +		pcmcia_release_configuration(link->handle); -    When a CARD_REMOVAL event is received, we immediately set a flag -    to block future accesses to this device.  All the functions that -    actually access the device should check this flag to make sure -    the card is still present. -     -======================================================================*/ +	return 0; +} -static int avma1cs_event(event_t event, int priority, -			  event_callback_args_t *args) +static int avma1cs_resume(struct pcmcia_device *dev)  { -    dev_link_t *link = args->client_data; +	dev_link_t *link = dev_to_instance(dev); -    DEBUG(1, "avma1cs_event(0x%06x)\n", event); -     -    switch (event) { -	case CS_EVENT_CARD_REMOVAL: -	    if (link->state & DEV_CONFIG) -		avma1cs_release(link); -	    break; -	case CS_EVENT_CARD_INSERTION: -	    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; -	    avma1cs_config(link); -	    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) +	link->state &= ~DEV_SUSPEND; +	if (link->state & DEV_CONFIG)  		pcmcia_request_configuration(link->handle, &link->conf); -	    break; -    } -    return 0; -} /* avma1cs_event */ + +	return 0; +} +  static struct pcmcia_device_id avma1cs_ids[] = {  	PCMCIA_DEVICE_PROD_ID12("AVM", "ISDN A", 0x95d42008, 0xadc9d4bb), @@ -505,10 +425,11 @@ static struct pcmcia_driver avma1cs_driver = {  	.drv		= {  		.name	= "avma1_cs",  	}, -	.attach		= avma1cs_attach, -	.event		= avma1cs_event, -	.detach		= avma1cs_detach, +	.probe		= avma1cs_attach, +	.remove		= avma1cs_detach,  	.id_table	= avma1cs_ids, +	.suspend	= avma1cs_suspend, +	.resume		= avma1cs_resume,  };  /*====================================================================*/ @@ -521,7 +442,6 @@ static int __init init_avma1_cs(void)  static void __exit exit_avma1_cs(void)  {  	pcmcia_unregister_driver(&avma1cs_driver); -	BUG_ON(dev_list != NULL);  }  module_init(init_avma1_cs); diff --git a/drivers/isdn/hisax/elsa_cs.c b/drivers/isdn/hisax/elsa_cs.c index 6fc6868de0b0..062fb8f0739f 100644 --- a/drivers/isdn/hisax/elsa_cs.c +++ b/drivers/isdn/hisax/elsa_cs.c @@ -96,8 +96,6 @@ module_param(protocol, int, 0);  static void elsa_cs_config(dev_link_t *link);  static void elsa_cs_release(dev_link_t *link); -static int elsa_cs_event(event_t event, int priority, -                          event_callback_args_t *args);  /*     The attach() and detach() entry points are used to create and destroy @@ -105,39 +103,9 @@ static int elsa_cs_event(event_t event, int priority,     needed to manage one actual PCMCIA card.  */ -static dev_link_t *elsa_cs_attach(void); -static void elsa_cs_detach(dev_link_t *); +static void elsa_cs_detach(struct pcmcia_device *p_dev);  /* -   The dev_info variable is the "key" that is used to match up this -   device driver with appropriate cards, through the card configuration -   database. -*/ - -static dev_info_t dev_info = "elsa_cs"; - -/* -   A linked list of "instances" of the elsa_cs device.  Each actual -   PCMCIA card corresponds to one device instance, and is described -   by one dev_link_t structure (defined in ds.h). - -   You may not want to use a linked list for this -- for example, the -   memory card driver uses an array of dev_link_t pointers, where minor -   device numbers are used to derive the corresponding array index. -*/ - -static dev_link_t *dev_list = NULL; - -/* -   A dev_link_t structure has fields for most things that are needed -   to keep track of a socket, but there will usually be some device -   specific information that also needs to be kept track of.  The -   'priv' pointer in a dev_link_t structure can be used to point to -   a device-specific private data structure, like this. - -   To simplify the data structure handling, we actually include the -   dev_link_t structure in the device's private data structure. -     A driver needs to provide a dev_node_t structure for each device     on a card.  In some cases, there is only one device per card (for     example, ethernet cards, modems).  In other cases, there may be @@ -171,18 +139,16 @@ typedef struct local_info_t {  ======================================================================*/ -static dev_link_t *elsa_cs_attach(void) +static int elsa_cs_attach(struct pcmcia_device *p_dev)  { -    client_reg_t client_reg;      dev_link_t *link;      local_info_t *local; -    int ret;      DEBUG(0, "elsa_cs_attach()\n");      /* Allocate space for private device-specific data */      local = kmalloc(sizeof(local_info_t), GFP_KERNEL); -    if (!local) return NULL; +    if (!local) return -ENOMEM;      memset(local, 0, sizeof(local_info_t));      local->cardnr = -1;      link = &local->link; link->priv = local; @@ -207,20 +173,13 @@ static dev_link_t *elsa_cs_attach(void)      link->conf.Vcc = 50;      link->conf.IntType = INT_MEMORY_AND_IO; -    /* Register with Card Services */ -    link->next = dev_list; -    dev_list = link; -    client_reg.dev_info = &dev_info; -    client_reg.Version = 0x0210; -    client_reg.event_callback_args.client_data = link; -    ret = pcmcia_register_client(&link->handle, &client_reg); -    if (ret != CS_SUCCESS) { -        cs_error(link->handle, RegisterClient, ret); -        elsa_cs_detach(link); -        return NULL; -    } +    link->handle = p_dev; +    p_dev->instance = link; -    return link; +    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; +    elsa_cs_config(link); + +    return 0;  } /* elsa_cs_attach */  /*====================================================================== @@ -232,32 +191,18 @@ static dev_link_t *elsa_cs_attach(void)  ======================================================================*/ -static void elsa_cs_detach(dev_link_t *link) +static void elsa_cs_detach(struct pcmcia_device *p_dev)  { -    dev_link_t **linkp; +    dev_link_t *link = dev_to_instance(p_dev);      local_info_t *info = link->priv; -    int ret;      DEBUG(0, "elsa_cs_detach(0x%p)\n", link); -    /* Locate device structure */ -    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) -        if (*linkp == link) break; -    if (*linkp == NULL) -        return; - -    if (link->state & DEV_CONFIG) -        elsa_cs_release(link); - -    /* Break the link with Card Services */ -    if (link->handle) { -        ret = pcmcia_deregister_client(link->handle); -	if (ret != CS_SUCCESS) -	    cs_error(link->handle, DeregisterClient, ret); +    if (link->state & DEV_CONFIG) { +	    info->busy = 1; +	    elsa_cs_release(link);      } -    /* Unlink device structure and free it */ -    *linkp = link->next;      kfree(info);  } /* elsa_cs_detach */ @@ -447,60 +392,31 @@ static void elsa_cs_release(dev_link_t *link)      link->state &= ~DEV_CONFIG;  } /* elsa_cs_release */ -/*====================================================================== - -    The card status event handler.  Mostly, this schedules other -    stuff to run after an event is received.  A CARD_REMOVAL event -    also sets some flags to discourage the net drivers from trying -    to talk to the card any more. +static int elsa_suspend(struct pcmcia_device *p_dev) +{ +	dev_link_t *link = dev_to_instance(p_dev); +	local_info_t *dev = link->priv; -    When a CARD_REMOVAL event is received, we immediately set a flag -    to block future accesses to this device.  All the functions that -    actually access the device should check this flag to make sure -    the card is still present. +	link->state |= DEV_SUSPEND; +        dev->busy = 1; +	if (link->state & DEV_CONFIG) +		pcmcia_release_configuration(link->handle); -======================================================================*/ +	return 0; +} -static int elsa_cs_event(event_t event, int priority, -                          event_callback_args_t *args) +static int elsa_resume(struct pcmcia_device *p_dev)  { -    dev_link_t *link = args->client_data; -    local_info_t *dev = link->priv; - -    DEBUG(1, "elsa_cs_event(%d)\n", event); +	dev_link_t *link = dev_to_instance(p_dev); +	local_info_t *dev = link->priv; -    switch (event) { -    case CS_EVENT_CARD_REMOVAL: -        link->state &= ~DEV_PRESENT; -        if (link->state & DEV_CONFIG) { -            ((local_info_t*)link->priv)->busy = 1; -	    elsa_cs_release(link); -        } -        break; -    case CS_EVENT_CARD_INSERTION: -        link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; -        elsa_cs_config(link); -        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); +	link->state &= ~DEV_SUSPEND; +	if (link->state & DEV_CONFIG) +		pcmcia_request_configuration(link->handle, &link->conf);          dev->busy = 0; -        break; -    } -    return 0; -} /* elsa_cs_event */ + +	return 0; +}  static struct pcmcia_device_id elsa_ids[] = {  	PCMCIA_DEVICE_PROD_ID12("ELSA AG (Aachen, Germany)", "MicroLink ISDN/MC ", 0x983de2c4, 0x333ba257), @@ -514,10 +430,11 @@ static struct pcmcia_driver elsa_cs_driver = {  	.drv		= {  		.name	= "elsa_cs",  	}, -	.attach		= elsa_cs_attach, -	.event		= elsa_cs_event, -	.detach		= elsa_cs_detach, +	.probe		= elsa_cs_attach, +	.remove		= elsa_cs_detach,  	.id_table	= elsa_ids, +	.suspend	= elsa_suspend, +	.resume		= elsa_resume,  };  static int __init init_elsa_cs(void) @@ -528,7 +445,6 @@ static int __init init_elsa_cs(void)  static void __exit exit_elsa_cs(void)  {  	pcmcia_unregister_driver(&elsa_cs_driver); -	BUG_ON(dev_list != NULL);  }  module_init(init_elsa_cs); diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c index dc334aab433e..6f5213a18a8d 100644 --- a/drivers/isdn/hisax/sedlbauer_cs.c +++ b/drivers/isdn/hisax/sedlbauer_cs.c @@ -97,8 +97,6 @@ module_param(protocol, int, 0);  static void sedlbauer_config(dev_link_t *link);  static void sedlbauer_release(dev_link_t *link); -static int sedlbauer_event(event_t event, int priority, -		       event_callback_args_t *args);  /*     The attach() and detach() entry points are used to create and destroy @@ -106,8 +104,7 @@ static int sedlbauer_event(event_t event, int priority,     needed to manage one actual PCMCIA card.  */ -static dev_link_t *sedlbauer_attach(void); -static void sedlbauer_detach(dev_link_t *); +static void sedlbauer_detach(struct pcmcia_device *p_dev);  /*     You'll also need to prototype all the functions that will actually @@ -117,35 +114,6 @@ static void sedlbauer_detach(dev_link_t *);  */  /* -   The dev_info variable is the "key" that is used to match up this -   device driver with appropriate cards, through the card configuration -   database. -*/ - -static dev_info_t dev_info = "sedlbauer_cs"; - -/* -   A linked list of "instances" of the sedlbauer device.  Each actual -   PCMCIA card corresponds to one device instance, and is described -   by one dev_link_t structure (defined in ds.h). - -   You may not want to use a linked list for this -- for example, the -   memory card driver uses an array of dev_link_t pointers, where minor -   device numbers are used to derive the corresponding array index. -*/ - -static dev_link_t *dev_list = NULL; - -/* -   A dev_link_t structure has fields for most things that are needed -   to keep track of a socket, but there will usually be some device -   specific information that also needs to be kept track of.  The -   'priv' pointer in a dev_link_t structure can be used to point to -   a device-specific private data structure, like this. - -   To simplify the data structure handling, we actually include the -   dev_link_t structure in the device's private data structure. -     A driver needs to provide a dev_node_t structure for each device     on a card.  In some cases, there is only one device per card (for     example, ethernet cards, modems).  In other cases, there may be @@ -180,18 +148,16 @@ typedef struct local_info_t {  ======================================================================*/ -static dev_link_t *sedlbauer_attach(void) +static int sedlbauer_attach(struct pcmcia_device *p_dev)  {      local_info_t *local;      dev_link_t *link; -    client_reg_t client_reg; -    int ret;      DEBUG(0, "sedlbauer_attach()\n");      /* Allocate space for private device-specific data */      local = kmalloc(sizeof(local_info_t), GFP_KERNEL); -    if (!local) return NULL; +    if (!local) return -ENOMEM;      memset(local, 0, sizeof(local_info_t));      local->cardnr = -1;      link = &local->link; link->priv = local; @@ -221,20 +187,13 @@ static dev_link_t *sedlbauer_attach(void)      link->conf.Vcc = 50;      link->conf.IntType = INT_MEMORY_AND_IO; -    /* Register with Card Services */ -    link->next = dev_list; -    dev_list = link; -    client_reg.dev_info = &dev_info; -    client_reg.Version = 0x0210; -    client_reg.event_callback_args.client_data = link; -    ret = pcmcia_register_client(&link->handle, &client_reg); -    if (ret != CS_SUCCESS) { -	cs_error(link->handle, RegisterClient, ret); -	sedlbauer_detach(link); -	return NULL; -    } +    link->handle = p_dev; +    p_dev->instance = link; + +    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; +    sedlbauer_config(link); -    return link; +    return 0;  } /* sedlbauer_attach */  /*====================================================================== @@ -246,39 +205,17 @@ static dev_link_t *sedlbauer_attach(void)  ======================================================================*/ -static void sedlbauer_detach(dev_link_t *link) +static void sedlbauer_detach(struct pcmcia_device *p_dev)  { -    dev_link_t **linkp; +    dev_link_t *link = dev_to_instance(p_dev);      DEBUG(0, "sedlbauer_detach(0x%p)\n", link); -     -    /* Locate device structure */ -    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) -	if (*linkp == link) break; -    if (*linkp == NULL) -	return; -    /* -       If the device is currently configured and active, we won't -       actually delete it yet.  Instead, it is marked so that when -       the release() function is called, that will trigger a proper -       detach(). -    */      if (link->state & DEV_CONFIG) { -#ifdef PCMCIA_DEBUG -	printk(KERN_DEBUG "sedlbauer_cs: detach postponed, '%s' " -	       "still locked\n", link->dev->dev_name); -#endif -	link->state |= DEV_STALE_LINK; -	return; +	    ((local_info_t *)link->priv)->stop = 1; +	    sedlbauer_release(link);      } -    /* Break the link with Card Services */ -    if (link->handle) -	pcmcia_deregister_client(link->handle); -     -    /* Unlink device structure, and free it */ -    *linkp = link->next;      /* This points to the parent local_info_t struct */      kfree(link->priv);  } /* sedlbauer_detach */ @@ -547,68 +484,34 @@ static void sedlbauer_release(dev_link_t *link)      if (link->irq.AssignedIRQ)  	pcmcia_release_irq(link->handle, &link->irq);      link->state &= ~DEV_CONFIG; -     -    if (link->state & DEV_STALE_LINK) -	sedlbauer_detach(link); -      } /* sedlbauer_release */ -/*====================================================================== - -    The card status event handler.  Mostly, this schedules other -    stuff to run after an event is received. - -    When a CARD_REMOVAL event is received, we immediately set a -    private flag to block future accesses to this device.  All the -    functions that actually access the device should check this flag -    to make sure the card is still present. -     -======================================================================*/ - -static int sedlbauer_event(event_t event, int priority, -		       event_callback_args_t *args) +static int sedlbauer_suspend(struct pcmcia_device *p_dev)  { -    dev_link_t *link = args->client_data; -    local_info_t *dev = link->priv; -     -    DEBUG(1, "sedlbauer_event(0x%06x)\n", event); -     -    switch (event) { -    case CS_EVENT_CARD_REMOVAL: -	link->state &= ~DEV_PRESENT; -	if (link->state & DEV_CONFIG) { -	    ((local_info_t *)link->priv)->stop = 1; -	    sedlbauer_release(link); -	} -	break; -    case CS_EVENT_CARD_INSERTION: -	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; -	sedlbauer_config(link); -	break; -    case CS_EVENT_PM_SUSPEND: +	dev_link_t *link = dev_to_instance(p_dev); +	local_info_t *dev = link->priv; +  	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: +		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; -	/* Fall through... */ -    case CS_EVENT_CARD_RESET:  	if (link->state & DEV_CONFIG) -	    pcmcia_request_configuration(link->handle, &link->conf); +		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; -} /* sedlbauer_event */ + +	return 0; +} +  static struct pcmcia_device_id sedlbauer_ids[] = {  	PCMCIA_DEVICE_PROD_ID123("SEDLBAUER", "speed star II", "V 3.1", 0x81fb79f5, 0xf3612e1d, 0x6b95c78a), @@ -627,10 +530,11 @@ static struct pcmcia_driver sedlbauer_driver = {  	.drv		= {  		.name	= "sedlbauer_cs",  	}, -	.attach		= sedlbauer_attach, -	.event		= sedlbauer_event, -	.detach		= sedlbauer_detach, +	.probe		= sedlbauer_attach, +	.remove		= sedlbauer_detach,  	.id_table	= sedlbauer_ids, +	.suspend	= sedlbauer_suspend, +	.resume		= sedlbauer_resume,  };  static int __init init_sedlbauer_cs(void) @@ -641,7 +545,6 @@ static int __init init_sedlbauer_cs(void)  static void __exit exit_sedlbauer_cs(void)  {  	pcmcia_unregister_driver(&sedlbauer_driver); -	BUG_ON(dev_list != NULL);  }  module_init(init_sedlbauer_cs); diff --git a/drivers/isdn/hisax/teles_cs.c b/drivers/isdn/hisax/teles_cs.c index 0ddef1bf778b..4e5c14c7240e 100644 --- a/drivers/isdn/hisax/teles_cs.c +++ b/drivers/isdn/hisax/teles_cs.c @@ -77,8 +77,6 @@ module_param(protocol, int, 0);  static void teles_cs_config(dev_link_t *link);  static void teles_cs_release(dev_link_t *link); -static int teles_cs_event(event_t event, int priority, -                          event_callback_args_t *args);  /*     The attach() and detach() entry points are used to create and destroy @@ -86,16 +84,7 @@ static int teles_cs_event(event_t event, int priority,     needed to manage one actual PCMCIA card.  */ -static dev_link_t *teles_attach(void); -static void teles_detach(dev_link_t *); - -/* -   The dev_info variable is the "key" that is used to match up this -   device driver with appropriate cards, through the card configuration -   database. -*/ - -static dev_info_t dev_info = "teles_cs"; +static void teles_detach(struct pcmcia_device *p_dev);  /*     A linked list of "instances" of the teles_cs device.  Each actual @@ -107,18 +96,7 @@ static dev_info_t dev_info = "teles_cs";     device numbers are used to derive the corresponding array index.  */ -static dev_link_t *dev_list = NULL; -  /* -   A dev_link_t structure has fields for most things that are needed -   to keep track of a socket, but there will usually be some device -   specific information that also needs to be kept track of.  The -   'priv' pointer in a dev_link_t structure can be used to point to -   a device-specific private data structure, like this. - -   To simplify the data structure handling, we actually include the -   dev_link_t structure in the device's private data structure. -     A driver needs to provide a dev_node_t structure for each device     on a card.  In some cases, there is only one device per card (for     example, ethernet cards, modems).  In other cases, there may be @@ -152,18 +130,16 @@ typedef struct local_info_t {  ======================================================================*/ -static dev_link_t *teles_attach(void) +static int teles_attach(struct pcmcia_device *p_dev)  { -    client_reg_t client_reg;      dev_link_t *link;      local_info_t *local; -    int ret;      DEBUG(0, "teles_attach()\n");      /* Allocate space for private device-specific data */      local = kmalloc(sizeof(local_info_t), GFP_KERNEL); -    if (!local) return NULL; +    if (!local) return -ENOMEM;      memset(local, 0, sizeof(local_info_t));      local->cardnr = -1;      link = &local->link; link->priv = local; @@ -188,20 +164,13 @@ static dev_link_t *teles_attach(void)      link->conf.Vcc = 50;      link->conf.IntType = INT_MEMORY_AND_IO; -    /* Register with Card Services */ -    link->next = dev_list; -    dev_list = link; -    client_reg.dev_info = &dev_info; -    client_reg.Version = 0x0210; -    client_reg.event_callback_args.client_data = link; -    ret = pcmcia_register_client(&link->handle, &client_reg); -    if (ret != CS_SUCCESS) { -        cs_error(link->handle, RegisterClient, ret); -        teles_detach(link); -        return NULL; -    } +    link->handle = p_dev; +    p_dev->instance = link; + +    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; +    teles_cs_config(link); -    return link; +    return 0;  } /* teles_attach */  /*====================================================================== @@ -213,32 +182,18 @@ static dev_link_t *teles_attach(void)  ======================================================================*/ -static void teles_detach(dev_link_t *link) +static void teles_detach(struct pcmcia_device *p_dev)  { -    dev_link_t **linkp; +    dev_link_t *link = dev_to_instance(p_dev);      local_info_t *info = link->priv; -    int ret;      DEBUG(0, "teles_detach(0x%p)\n", link); -    /* Locate device structure */ -    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) -        if (*linkp == link) break; -    if (*linkp == NULL) -        return; - -    if (link->state & DEV_CONFIG) -        teles_cs_release(link); - -    /* Break the link with Card Services */ -    if (link->handle) { -        ret = pcmcia_deregister_client(link->handle); -	if (ret != CS_SUCCESS) -	    cs_error(link->handle, DeregisterClient, ret); +    if (link->state & DEV_CONFIG) { +	    info->busy = 1; +	    teles_cs_release(link);      } -    /* Unlink device structure and free it */ -    *linkp = link->next;      kfree(info);  } /* teles_detach */ @@ -428,60 +383,32 @@ static void teles_cs_release(dev_link_t *link)      link->state &= ~DEV_CONFIG;  } /* teles_cs_release */ -/*====================================================================== - -    The card status event handler.  Mostly, this schedules other -    stuff to run after an event is received.  A CARD_REMOVAL event -    also sets some flags to discourage the net drivers from trying -    to talk to the card any more. +static int teles_suspend(struct pcmcia_device *p_dev) +{ +	dev_link_t *link = dev_to_instance(p_dev); +	local_info_t *dev = link->priv; -    When a CARD_REMOVAL event is received, we immediately set a flag -    to block future accesses to this device.  All the functions that -    actually access the device should check this flag to make sure -    the card is still present. +	link->state |= DEV_SUSPEND; +        dev->busy = 1; +	if (link->state & DEV_CONFIG) +		pcmcia_release_configuration(link->handle); -======================================================================*/ +	return 0; +} -static int teles_cs_event(event_t event, int priority, -                          event_callback_args_t *args) +static int teles_resume(struct pcmcia_device *p_dev)  { -    dev_link_t *link = args->client_data; -    local_info_t *dev = link->priv; - -    DEBUG(1, "teles_cs_event(%d)\n", event); +	dev_link_t *link = dev_to_instance(p_dev); +	local_info_t *dev = link->priv; -    switch (event) { -    case CS_EVENT_CARD_REMOVAL: -        link->state &= ~DEV_PRESENT; -        if (link->state & DEV_CONFIG) { -            ((local_info_t*)link->priv)->busy = 1; -	    teles_cs_release(link); -        } -        break; -    case CS_EVENT_CARD_INSERTION: -        link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; -        teles_cs_config(link); -        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); +	link->state &= ~DEV_SUSPEND; +	if (link->state & DEV_CONFIG) +		pcmcia_request_configuration(link->handle, &link->conf);          dev->busy = 0; -        break; -    } -    return 0; -} /* teles_cs_event */ + +	return 0; +} +  static struct pcmcia_device_id teles_ids[] = {  	PCMCIA_DEVICE_PROD_ID12("TELES", "S0/PC", 0x67b50eae, 0xe9e70119), @@ -494,10 +421,11 @@ static struct pcmcia_driver teles_cs_driver = {  	.drv		= {  		.name	= "teles_cs",  	}, -	.attach		= teles_attach, -	.event		= teles_cs_event, -	.detach		= teles_detach, +	.probe		= teles_attach, +	.remove		= teles_detach,  	.id_table       = teles_ids, +	.suspend	= teles_suspend, +	.resume		= teles_resume,  };  static int __init init_teles_cs(void) @@ -508,7 +436,6 @@ static int __init init_teles_cs(void)  static void __exit exit_teles_cs(void)  {  	pcmcia_unregister_driver(&teles_cs_driver); -	BUG_ON(dev_list != NULL);  }  module_init(init_teles_cs); diff --git a/drivers/mtd/maps/pcmciamtd.c b/drivers/mtd/maps/pcmciamtd.c index af24216a0626..f0f8916da7ad 100644 --- a/drivers/mtd/maps/pcmciamtd.c +++ b/drivers/mtd/maps/pcmciamtd.c @@ -66,9 +66,6 @@ struct pcmciamtd_dev {  }; -static dev_info_t dev_info = "pcmciamtd"; -static dev_link_t *dev_list; -  /* Module parameters */  /* 2 = do 16-bit transfers, 1 = do 8-bit transfers */ @@ -691,55 +688,21 @@ static void pcmciamtd_config(dev_link_t *link)  } -/* The card status event handler.  Mostly, this schedules other - * stuff to run after an event is received.  A CARD_REMOVAL event - * also sets some flags to discourage the driver from trying - * to talk to the card any more. - */ +static int pcmciamtd_suspend(struct pcmcia_device *dev) +{ +	DEBUG(2, "EVENT_PM_RESUME"); + +	/* get_lock(link); */ + +	return 0; +} -static int pcmciamtd_event(event_t event, int priority, -			event_callback_args_t *args) +static int pcmciamtd_resume(struct pcmcia_device *dev)  { -	dev_link_t *link = args->client_data; - -	DEBUG(1, "event=0x%06x", event); -	switch (event) { -	case CS_EVENT_CARD_REMOVAL: -		DEBUG(2, "EVENT_CARD_REMOVAL"); -		link->state &= ~DEV_PRESENT; -		if (link->state & DEV_CONFIG) { -			struct pcmciamtd_dev *dev = link->priv; -			if(dev->mtd_info) { -				del_mtd_device(dev->mtd_info); -				info("mtd%d: Removed", dev->mtd_info->index); -			} -			pcmciamtd_release(link); -		} -		break; -	case CS_EVENT_CARD_INSERTION: -		DEBUG(2, "EVENT_CARD_INSERTION"); -		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; -		pcmciamtd_config(link); -		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: -		DEBUG(2, "Unknown event %d", event); -	} +	DEBUG(2, "EVENT_PM_SUSPEND"); + +	/* free_lock(link); */ +  	return 0;  } @@ -750,23 +713,21 @@ static int pcmciamtd_event(event_t event, int priority,   * when the device is released.   */ -static void pcmciamtd_detach(dev_link_t *link) +static void pcmciamtd_detach(struct pcmcia_device *p_dev)  { +	dev_link_t *link = dev_to_instance(p_dev); +  	DEBUG(3, "link=0x%p", link);  	if(link->state & DEV_CONFIG) { -		pcmciamtd_release(link); -	} +		struct pcmciamtd_dev *dev = link->priv; +		if(dev->mtd_info) { +			del_mtd_device(dev->mtd_info); +			info("mtd%d: Removed", dev->mtd_info->index); +		} -	if (link->handle) { -		int ret; -		DEBUG(2, "Deregistering with card services"); -		ret = pcmcia_deregister_client(link->handle); -		if (ret != CS_SUCCESS) -			cs_error(link->handle, DeregisterClient, ret); +		pcmciamtd_release(link);  	} - -	link->state |= DEV_STALE_LINK;  } @@ -775,16 +736,14 @@ static void pcmciamtd_detach(dev_link_t *link)   * with Card Services.   */ -static dev_link_t *pcmciamtd_attach(void) +static int pcmciamtd_attach(struct pcmcia_device *p_dev)  {  	struct pcmciamtd_dev *dev;  	dev_link_t *link; -	client_reg_t client_reg; -	int ret;  	/* Create new memory card device */  	dev = kmalloc(sizeof(*dev), GFP_KERNEL); -	if (!dev) return NULL; +	if (!dev) return -ENOMEM;  	DEBUG(1, "dev=0x%p", dev);  	memset(dev, 0, sizeof(*dev)); @@ -794,22 +753,14 @@ static dev_link_t *pcmciamtd_attach(void)  	link->conf.Attributes = 0;  	link->conf.IntType = INT_MEMORY; -	link->next = dev_list; -	dev_list = link; - -	/* Register with Card Services */ -	client_reg.dev_info = &dev_info; -	client_reg.Version = 0x0210; -	client_reg.event_callback_args.client_data = link; -	DEBUG(2, "Calling RegisterClient"); -	ret = pcmcia_register_client(&link->handle, &client_reg); -	if (ret != 0) { -		cs_error(link->handle, RegisterClient, ret); -		pcmciamtd_detach(link); -		return NULL; -	} -	DEBUG(2, "link = %p", link); -	return link; +	link->next = NULL; +	link->handle = p_dev; +	p_dev->instance = link; + +	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; +	pcmciamtd_config(link); + +	return 0;  }  static struct pcmcia_device_id pcmciamtd_ids[] = { @@ -843,11 +794,12 @@ static struct pcmcia_driver pcmciamtd_driver = {  	.drv		= {  		.name	= "pcmciamtd"  	}, -	.attach		= pcmciamtd_attach, -	.event		= pcmciamtd_event, -	.detach		= pcmciamtd_detach, +	.probe		= pcmciamtd_attach, +	.remove		= pcmciamtd_detach,  	.owner		= THIS_MODULE,  	.id_table	= pcmciamtd_ids, +	.suspend	= pcmciamtd_suspend, +	.resume		= pcmciamtd_resume,  }; @@ -875,7 +827,6 @@ static void __exit exit_pcmciamtd(void)  {  	DEBUG(1, DRIVER_DESC " unloading");  	pcmcia_unregister_driver(&pcmciamtd_driver); -	BUG_ON(dev_list != NULL);  }  module_init(init_pcmciamtd); diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c index 71fd41122c91..48774efeec71 100644 --- a/drivers/net/pcmcia/3c574_cs.c +++ b/drivers/net/pcmcia/3c574_cs.c @@ -227,8 +227,6 @@ static char mii_preamble_required = 0;  static void tc574_config(dev_link_t *link);  static void tc574_release(dev_link_t *link); -static int tc574_event(event_t event, int priority, -					   event_callback_args_t *args);  static void mdio_sync(kio_addr_t ioaddr, int bits);  static int mdio_read(kio_addr_t ioaddr, int phy_id, int location); @@ -250,12 +248,7 @@ static int el3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);  static struct ethtool_ops netdev_ethtool_ops;  static void set_rx_mode(struct net_device *dev); -static dev_info_t dev_info = "3c574_cs"; - -static dev_link_t *tc574_attach(void); -static void tc574_detach(dev_link_t *); - -static dev_link_t *dev_list; +static void tc574_detach(struct pcmcia_device *p_dev);  /*  	tc574_attach() creates an "instance" of the driver, allocating @@ -263,20 +256,18 @@ static dev_link_t *dev_list;  	with Card Services.  */ -static dev_link_t *tc574_attach(void) +static int tc574_attach(struct pcmcia_device *p_dev)  {  	struct el3_private *lp; -	client_reg_t client_reg;  	dev_link_t *link;  	struct net_device *dev; -	int ret;  	DEBUG(0, "3c574_attach()\n");  	/* Create the PC card device object. */  	dev = alloc_etherdev(sizeof(struct el3_private));  	if (!dev) -		return NULL; +		return -ENOMEM;  	lp = netdev_priv(dev);  	link = &lp->link;  	link->priv = dev; @@ -307,20 +298,13 @@ static dev_link_t *tc574_attach(void)  	dev->watchdog_timeo = TX_TIMEOUT;  #endif -	/* Register with Card Services */ -	link->next = dev_list; -	dev_list = link; -	client_reg.dev_info = &dev_info; -	client_reg.Version = 0x0210; -	client_reg.event_callback_args.client_data = link; -	ret = pcmcia_register_client(&link->handle, &client_reg); -	if (ret != 0) { -		cs_error(link->handle, RegisterClient, ret); -		tc574_detach(link); -		return NULL; -	} +	link->handle = p_dev; +	p_dev->instance = link; -	return link; +	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; +	tc574_config(link); + +	return 0;  } /* tc574_attach */  /* @@ -332,30 +316,19 @@ static dev_link_t *tc574_attach(void)  */ -static void tc574_detach(dev_link_t *link) +static void tc574_detach(struct pcmcia_device *p_dev)  { +	dev_link_t *link = dev_to_instance(p_dev);  	struct net_device *dev = link->priv; -	dev_link_t **linkp;  	DEBUG(0, "3c574_detach(0x%p)\n", link); -	/* Locate device structure */ -	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) -		if (*linkp == link) break; -	if (*linkp == NULL) -		return; -  	if (link->dev)  		unregister_netdev(dev);  	if (link->state & DEV_CONFIG)  		tc574_release(link); -	if (link->handle) -		pcmcia_deregister_client(link->handle); - -	/* Unlink device structure, free bits */ -	*linkp = link->next;  	free_netdev(dev);  } /* tc574_detach */ @@ -547,56 +520,37 @@ static void tc574_release(dev_link_t *link)  	link->state &= ~DEV_CONFIG;  } -/* -	The card status event handler.  Mostly, this schedules other -	stuff to run after an event is received.  A CARD_REMOVAL event -	also sets some flags to discourage the net drivers from trying -	to talk to the card any more. -*/ - -static int tc574_event(event_t event, int priority, -					   event_callback_args_t *args) +static int tc574_suspend(struct pcmcia_device *p_dev)  { -	dev_link_t *link = args->client_data; +	dev_link_t *link = dev_to_instance(p_dev);  	struct net_device *dev = link->priv; -	DEBUG(1, "3c574_event(0x%06x)\n", event); - -	switch (event) { -	case CS_EVENT_CARD_REMOVAL: -		link->state &= ~DEV_PRESENT; -		if (link->state & DEV_CONFIG) +	link->state |= DEV_SUSPEND; +	if (link->state & DEV_CONFIG) { +		if (link->open)  			netif_device_detach(dev); -		break; -	case CS_EVENT_CARD_INSERTION: -		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; -		tc574_config(link); -		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); -			} +		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);  		} -		break;  	} +  	return 0; -} /* tc574_event */ +}  static void dump_status(struct net_device *dev)  { @@ -1292,10 +1246,11 @@ static struct pcmcia_driver tc574_driver = {  	.drv		= {  		.name	= "3c574_cs",  	}, -	.attach		= tc574_attach, -	.event		= tc574_event, -	.detach		= tc574_detach, +	.probe		= tc574_attach, +	.remove		= tc574_detach,  	.id_table       = tc574_ids, +	.suspend	= tc574_suspend, +	.resume		= tc574_resume,  };  static int __init init_tc574(void) @@ -1306,7 +1261,6 @@ static int __init init_tc574(void)  static void __exit exit_tc574(void)  {  	pcmcia_unregister_driver(&tc574_driver); -	BUG_ON(dev_list != NULL);  }  module_init(init_tc574); diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c index d83fdd8c1943..1c3c9c666f74 100644 --- a/drivers/net/pcmcia/3c589_cs.c +++ b/drivers/net/pcmcia/3c589_cs.c @@ -143,8 +143,6 @@ DRV_NAME ".c " DRV_VERSION " 2001/10/13 00:08:50 (David Hinds)";  static void tc589_config(dev_link_t *link);  static void tc589_release(dev_link_t *link); -static int tc589_event(event_t event, int priority, -		       event_callback_args_t *args);  static u16 read_eeprom(kio_addr_t ioaddr, int index);  static void tc589_reset(struct net_device *dev); @@ -161,12 +159,7 @@ static void el3_tx_timeout(struct net_device *dev);  static void set_multicast_list(struct net_device *dev);  static struct ethtool_ops netdev_ethtool_ops; -static dev_info_t dev_info = "3c589_cs"; - -static dev_link_t *tc589_attach(void); -static void tc589_detach(dev_link_t *); - -static dev_link_t *dev_list; +static void tc589_detach(struct pcmcia_device *p_dev);  /*====================================================================== @@ -176,20 +169,18 @@ static dev_link_t *dev_list;  ======================================================================*/ -static dev_link_t *tc589_attach(void) +static int tc589_attach(struct pcmcia_device *p_dev)  {      struct el3_private *lp; -    client_reg_t client_reg;      dev_link_t *link;      struct net_device *dev; -    int ret;      DEBUG(0, "3c589_attach()\n"); -     +      /* Create new ethernet device */      dev = alloc_etherdev(sizeof(struct el3_private));      if (!dev) -	 return NULL; +	 return -ENOMEM;      lp = netdev_priv(dev);      link = &lp->link;      link->priv = dev; @@ -206,7 +197,7 @@ static dev_link_t *tc589_attach(void)      link->conf.IntType = INT_MEMORY_AND_IO;      link->conf.ConfigIndex = 1;      link->conf.Present = PRESENT_OPTION; -     +      /* The EL3-specific entries in the device structure. */      SET_MODULE_OWNER(dev);      dev->hard_start_xmit = &el3_start_xmit; @@ -221,20 +212,13 @@ static dev_link_t *tc589_attach(void)  #endif      SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); -    /* Register with Card Services */ -    link->next = dev_list; -    dev_list = link; -    client_reg.dev_info = &dev_info; -    client_reg.Version = 0x0210; -    client_reg.event_callback_args.client_data = link; -    ret = pcmcia_register_client(&link->handle, &client_reg); -    if (ret != 0) { -	cs_error(link->handle, RegisterClient, ret); -	tc589_detach(link); -	return NULL; -    } -     -    return link; +    link->handle = p_dev; +    p_dev->instance = link; + +    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; +    tc589_config(link); + +    return 0;  } /* tc589_attach */  /*====================================================================== @@ -246,30 +230,19 @@ static dev_link_t *tc589_attach(void)  ======================================================================*/ -static void tc589_detach(dev_link_t *link) +static void tc589_detach(struct pcmcia_device *p_dev)  { +    dev_link_t *link = dev_to_instance(p_dev);      struct net_device *dev = link->priv; -    dev_link_t **linkp; -     +      DEBUG(0, "3c589_detach(0x%p)\n", link); -     -    /* Locate device structure */ -    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) -	if (*linkp == link) break; -    if (*linkp == NULL) -	return;      if (link->dev)  	unregister_netdev(dev);      if (link->state & DEV_CONFIG)  	tc589_release(link); -     -    if (link->handle) -	pcmcia_deregister_client(link->handle); -     -    /* Unlink device structure, free bits */ -    *linkp = link->next; +      free_netdev(dev);  } /* tc589_detach */ @@ -421,58 +394,37 @@ static void tc589_release(dev_link_t *link)      link->state &= ~DEV_CONFIG;  } -/*====================================================================== - -    The card status event handler.  Mostly, this schedules other -    stuff to run after an event is received.  A CARD_REMOVAL event -    also sets some flags to discourage the net drivers from trying -    to talk to the card any more. -     -======================================================================*/ - -static int tc589_event(event_t event, int priority, -		       event_callback_args_t *args) +static int tc589_suspend(struct pcmcia_device *p_dev)  { -    dev_link_t *link = args->client_data; -    struct net_device *dev = link->priv; -     -    DEBUG(1, "3c589_event(0x%06x)\n", event); -     -    switch (event) { -    case CS_EVENT_CARD_REMOVAL: -	link->state &= ~DEV_PRESENT; -	if (link->state & DEV_CONFIG) -	    netif_device_detach(dev); -	break; -    case CS_EVENT_CARD_INSERTION: -	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; -	tc589_config(link); -	break; -    case CS_EVENT_PM_SUSPEND: +	dev_link_t *link = dev_to_instance(p_dev); +	struct net_device *dev = link->priv; +  	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); +		if (link->open) +			netif_device_detach(dev); +		pcmcia_release_configuration(link->handle);  	} -	break; -    case CS_EVENT_PM_RESUME: + +	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; -	/* 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); -	    } +		pcmcia_request_configuration(link->handle, &link->conf); +		if (link->open) { +			tc589_reset(dev); +			netif_device_attach(dev); +		}  	} -	break; -    } -    return 0; -} /* tc589_event */ + +	return 0; +}  /*====================================================================*/ @@ -1067,10 +1019,11 @@ static struct pcmcia_driver tc589_driver = {  	.drv		= {  		.name	= "3c589_cs",  	}, -	.attach		= tc589_attach, -	.event		= tc589_event, -	.detach		= tc589_detach, +	.probe		= tc589_attach, +	.remove		= tc589_detach,          .id_table       = tc589_ids, +	.suspend	= tc589_suspend, +	.resume		= tc589_resume,  };  static int __init init_tc589(void) @@ -1081,7 +1034,6 @@ static int __init init_tc589(void)  static void __exit exit_tc589(void)  {  	pcmcia_unregister_driver(&tc589_driver); -	BUG_ON(dev_list != NULL);  }  module_init(init_tc589); diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c index 8bb4e85689ea..01ddfc8cce3f 100644 --- a/drivers/net/pcmcia/axnet_cs.c +++ b/drivers/net/pcmcia/axnet_cs.c @@ -87,8 +87,6 @@ static char *version =  static void axnet_config(dev_link_t *link);  static void axnet_release(dev_link_t *link); -static int axnet_event(event_t event, int priority, -		       event_callback_args_t *args);  static int axnet_open(struct net_device *dev);  static int axnet_close(struct net_device *dev);  static int axnet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); @@ -107,11 +105,7 @@ static void block_input(struct net_device *dev, int count,  static void block_output(struct net_device *dev, int count,  			 const u_char *buf, const int start_page); -static dev_link_t *axnet_attach(void); -static void axnet_detach(dev_link_t *); - -static dev_info_t dev_info = "axnet_cs"; -static dev_link_t *dev_list; +static void axnet_detach(struct pcmcia_device *p_dev);  static void axdev_setup(struct net_device *dev);  static void AX88190_init(struct net_device *dev, int startp); @@ -147,13 +141,11 @@ static inline axnet_dev_t *PRIV(struct net_device *dev)  ======================================================================*/ -static dev_link_t *axnet_attach(void) +static int axnet_attach(struct pcmcia_device *p_dev)  {      axnet_dev_t *info;      dev_link_t *link;      struct net_device *dev; -    client_reg_t client_reg; -    int ret;      DEBUG(0, "axnet_attach()\n"); @@ -161,7 +153,7 @@ static dev_link_t *axnet_attach(void)  			"eth%d", axdev_setup);      if (!dev) -	return NULL; +	return -ENOMEM;      info = PRIV(dev);      link = &info->link; @@ -176,20 +168,13 @@ static dev_link_t *axnet_attach(void)      dev->do_ioctl = &axnet_ioctl;      SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); -    /* Register with Card Services */ -    link->next = dev_list; -    dev_list = link; -    client_reg.dev_info = &dev_info; -    client_reg.Version = 0x0210; -    client_reg.event_callback_args.client_data = link; -    ret = pcmcia_register_client(&link->handle, &client_reg); -    if (ret != CS_SUCCESS) { -	cs_error(link->handle, RegisterClient, ret); -	axnet_detach(link); -	return NULL; -    } +    link->handle = p_dev; +    p_dev->instance = link; -    return link; +    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; +    axnet_config(link); + +    return 0;  } /* axnet_attach */  /*====================================================================== @@ -201,30 +186,19 @@ static dev_link_t *axnet_attach(void)  ======================================================================*/ -static void axnet_detach(dev_link_t *link) +static void axnet_detach(struct pcmcia_device *p_dev)  { +    dev_link_t *link = dev_to_instance(p_dev);      struct net_device *dev = link->priv; -    dev_link_t **linkp;      DEBUG(0, "axnet_detach(0x%p)\n", link); -    /* Locate device structure */ -    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) -	if (*linkp == link) break; -    if (*linkp == NULL) -	return; -      if (link->dev)  	unregister_netdev(dev);      if (link->state & DEV_CONFIG)  	axnet_release(link); -    if (link->handle) -	pcmcia_deregister_client(link->handle); - -    /* Unlink device structure, free bits */ -    *linkp = link->next;      free_netdev(dev);  } /* axnet_detach */ @@ -490,59 +464,39 @@ static void axnet_release(dev_link_t *link)      link->state &= ~DEV_CONFIG;  } -/*====================================================================== - -    The card status event handler.  Mostly, this schedules other -    stuff to run after an event is received.  A CARD_REMOVAL event -    also sets some flags to discourage the net drivers from trying -    to talk to the card any more. - -======================================================================*/ - -static int axnet_event(event_t event, int priority, -		       event_callback_args_t *args) +static int axnet_suspend(struct pcmcia_device *p_dev)  { -    dev_link_t *link = args->client_data; -    struct net_device *dev = link->priv; +	dev_link_t *link = dev_to_instance(p_dev); +	struct net_device *dev = link->priv; -    DEBUG(2, "axnet_event(0x%06x)\n", event); - -    switch (event) { -    case CS_EVENT_CARD_REMOVAL: -	link->state &= ~DEV_PRESENT; -	if (link->state & DEV_CONFIG) -	    netif_device_detach(dev); -	break; -    case CS_EVENT_CARD_INSERTION: -	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; -	axnet_config(link); -	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); +		if (link->open) +			netif_device_detach(dev); +		pcmcia_release_configuration(link->handle);  	} -	break; -    case CS_EVENT_PM_RESUME: + +	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; -	/* 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); -	    } +		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; -} /* axnet_event */ + +	return 0; +} +  /*====================================================================== @@ -616,7 +570,7 @@ static int axnet_open(struct net_device *dev)      link->open++; -    request_irq(dev->irq, ei_irq_wrapper, SA_SHIRQ, dev_info, dev); +    request_irq(dev->irq, ei_irq_wrapper, SA_SHIRQ, "axnet_cs", dev);      info->link_status = 0x00;      init_timer(&info->watchdog); @@ -877,10 +831,11 @@ static struct pcmcia_driver axnet_cs_driver = {  	.drv		= {  		.name	= "axnet_cs",  	}, -	.attach		= axnet_attach, -	.event		= axnet_event, -	.detach		= axnet_detach, +	.probe		= axnet_attach, +	.remove		= axnet_detach,  	.id_table       = axnet_ids, +	.suspend	= axnet_suspend, +	.resume		= axnet_resume,  };  static int __init init_axnet_cs(void) @@ -891,7 +846,6 @@ static int __init init_axnet_cs(void)  static void __exit exit_axnet_cs(void)  {  	pcmcia_unregister_driver(&axnet_cs_driver); -	BUG_ON(dev_list != NULL);  }  module_init(init_axnet_cs); diff --git a/drivers/net/pcmcia/com20020_cs.c b/drivers/net/pcmcia/com20020_cs.c index b9355d9498a3..2827a48ea37c 100644 --- a/drivers/net/pcmcia/com20020_cs.c +++ b/drivers/net/pcmcia/com20020_cs.c @@ -120,15 +120,8 @@ MODULE_LICENSE("GPL");  static void com20020_config(dev_link_t *link);  static void com20020_release(dev_link_t *link); -static int com20020_event(event_t event, int priority, -                       event_callback_args_t *args); -static dev_info_t dev_info = "com20020_cs"; - -static dev_link_t *com20020_attach(void); -static void com20020_detach(dev_link_t *); - -static dev_link_t *dev_list; +static void com20020_detach(struct pcmcia_device *p_dev);  /*====================================================================*/ @@ -145,21 +138,19 @@ typedef struct com20020_dev_t {  ======================================================================*/ -static dev_link_t *com20020_attach(void) +static int com20020_attach(struct pcmcia_device *p_dev)  { -    client_reg_t client_reg;      dev_link_t *link;      com20020_dev_t *info;      struct net_device *dev; -    int ret;      struct arcnet_local *lp; -     +      DEBUG(0, "com20020_attach()\n");      /* Create new network device */      link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);      if (!link) -	return NULL; +	return -ENOMEM;      info = kmalloc(sizeof(struct com20020_dev_t), GFP_KERNEL);      if (!info) @@ -191,30 +182,19 @@ static dev_link_t *com20020_attach(void)      link->conf.IntType = INT_MEMORY_AND_IO;      link->conf.Present = PRESENT_OPTION; -      link->irq.Instance = info->dev = dev;      link->priv = info; -    /* Register with Card Services */ -    link->next = dev_list; -    dev_list = link; -    client_reg.dev_info = &dev_info; -    client_reg.Version = 0x0210; -    client_reg.event_callback_args.client_data = link; -    ret = pcmcia_register_client(&link->handle, &client_reg); -    if (ret != 0) { -        cs_error(link->handle, RegisterClient, ret); -        com20020_detach(link); -        return NULL; -    } +    link->state |= DEV_PRESENT; +    com20020_config(link); -    return link; +    return 0;  fail_alloc_dev:      kfree(info);  fail_alloc_info:      kfree(link); -    return NULL; +    return -ENOMEM;  } /* com20020_attach */  /*====================================================================== @@ -226,29 +206,21 @@ fail_alloc_info:  ======================================================================*/ -static void com20020_detach(dev_link_t *link) +static void com20020_detach(struct pcmcia_device *p_dev)  { +    dev_link_t *link = dev_to_instance(p_dev);      struct com20020_dev_t *info = link->priv; -    dev_link_t **linkp; -    struct net_device *dev;  -     +    struct net_device *dev = info->dev; +      DEBUG(1,"detach...\n");      DEBUG(0, "com20020_detach(0x%p)\n", link); -    /* Locate device structure */ -    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) -        if (*linkp == link) break; -    if (*linkp == NULL) -        return; - -    dev = info->dev; -      if (link->dev) {  	DEBUG(1,"unregister...\n");  	unregister_netdev(dev); -	     +  	/*  	 * this is necessary because we register our IRQ separately  	 * from card services. @@ -260,12 +232,8 @@ static void com20020_detach(dev_link_t *link)      if (link->state & DEV_CONFIG)          com20020_release(link); -    if (link->handle) -        pcmcia_deregister_client(link->handle); -      /* Unlink device structure, free bits */      DEBUG(1,"unlinking...\n"); -    *linkp = link->next;      if (link->priv)      {  	dev = info->dev; @@ -421,61 +389,41 @@ static void com20020_release(dev_link_t *link)      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; -    The card status event handler.  Mostly, this schedules other -    stuff to run after an event is received.  A CARD_REMOVAL event -    also sets some flags to discourage the net drivers from trying -    to talk to the card any more. +	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_event(event_t event, int priority, -			  event_callback_args_t *args) +static int com20020_resume(struct pcmcia_device *p_dev)  { -    dev_link_t *link = args->client_data; -    com20020_dev_t *info = link->priv; -    struct net_device *dev = info->dev; +	dev_link_t *link = dev_to_instance(p_dev); +	com20020_dev_t *info = link->priv; +	struct net_device *dev = info->dev; -    DEBUG(1, "com20020_event(0x%06x)\n", event); -     -    switch (event) { -    case CS_EVENT_CARD_REMOVAL: -        link->state &= ~DEV_PRESENT; -        if (link->state & DEV_CONFIG) -            netif_device_detach(dev); -        break; -    case CS_EVENT_CARD_INSERTION: -        link->state |= DEV_PRESENT; -	com20020_config(link);  -	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: +	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; -            } +		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; -} /* com20020_event */ + +	return 0; +}  static struct pcmcia_device_id com20020_ids[] = {  	PCMCIA_DEVICE_PROD_ID12("Contemporary Control Systems, Inc.", "PCM20 Arcnet Adapter", 0x59991666, 0x95dfffaf), @@ -488,10 +436,11 @@ static struct pcmcia_driver com20020_cs_driver = {  	.drv		= {  		.name	= "com20020_cs",  	}, -	.attach		= com20020_attach, -	.event		= com20020_event, -	.detach		= com20020_detach, +	.probe		= com20020_attach, +	.remove		= com20020_detach,  	.id_table	= com20020_ids, +	.suspend	= com20020_suspend, +	.resume		= com20020_resume,  };  static int __init init_com20020_cs(void) @@ -502,7 +451,6 @@ static int __init init_com20020_cs(void)  static void __exit exit_com20020_cs(void)  {  	pcmcia_unregister_driver(&com20020_cs_driver); -	BUG_ON(dev_list != NULL);  }  module_init(init_com20020_cs); diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c index 356f50909222..28fe2fb4d6c0 100644 --- a/drivers/net/pcmcia/fmvj18x_cs.c +++ b/drivers/net/pcmcia/fmvj18x_cs.c @@ -88,10 +88,7 @@ static void fmvj18x_config(dev_link_t *link);  static int fmvj18x_get_hwinfo(dev_link_t *link, u_char *node_id);  static int fmvj18x_setup_mfc(dev_link_t *link);  static void fmvj18x_release(dev_link_t *link); -static int fmvj18x_event(event_t event, int priority, -			  event_callback_args_t *args); -static dev_link_t *fmvj18x_attach(void); -static void fmvj18x_detach(dev_link_t *); +static void fmvj18x_detach(struct pcmcia_device *p_dev);  /*      LAN controller(MBH86960A) specific routines @@ -108,9 +105,6 @@ static void set_rx_mode(struct net_device *dev);  static void fjn_tx_timeout(struct net_device *dev);  static struct ethtool_ops netdev_ethtool_ops; -static dev_info_t dev_info = "fmvj18x_cs"; -static dev_link_t *dev_list; -  /*      card type   */ @@ -234,20 +228,18 @@ typedef struct local_info_t {  #define BANK_1U              0x24 /* bank 1 (CONFIG_1) */  #define BANK_2U              0x28 /* bank 2 (CONFIG_1) */ -static dev_link_t *fmvj18x_attach(void) +static int fmvj18x_attach(struct pcmcia_device *p_dev)  {      local_info_t *lp;      dev_link_t *link;      struct net_device *dev; -    client_reg_t client_reg; -    int ret; -     +      DEBUG(0, "fmvj18x_attach()\n");      /* Make up a FMVJ18x specific data structure */      dev = alloc_etherdev(sizeof(local_info_t));      if (!dev) -	return NULL; +	return -ENOMEM;      lp = netdev_priv(dev);      link = &lp->link;      link->priv = dev; @@ -262,7 +254,7 @@ static dev_link_t *fmvj18x_attach(void)      link->irq.IRQInfo1 = IRQ_LEVEL_ID;      link->irq.Handler = &fjn_interrupt;      link->irq.Instance = dev; -     +      /* General socket configuration */      link->conf.Attributes = CONF_ENABLE_IRQ;      link->conf.Vcc = 50; @@ -281,37 +273,24 @@ static dev_link_t *fmvj18x_attach(void)      dev->watchdog_timeo = TX_TIMEOUT;  #endif      SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); -     -    /* Register with Card Services */ -    link->next = dev_list; -    dev_list = link; -    client_reg.dev_info = &dev_info; -    client_reg.Version = 0x0210; -    client_reg.event_callback_args.client_data = link; -    ret = pcmcia_register_client(&link->handle, &client_reg); -    if (ret != 0) { -	cs_error(link->handle, RegisterClient, ret); -	fmvj18x_detach(link); -	return NULL; -    } -    return link; +    link->handle = p_dev; +    p_dev->instance = link; + +    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; +    fmvj18x_config(link); + +    return 0;  } /* fmvj18x_attach */  /*====================================================================*/ -static void fmvj18x_detach(dev_link_t *link) +static void fmvj18x_detach(struct pcmcia_device *p_dev)  { +    dev_link_t *link = dev_to_instance(p_dev);      struct net_device *dev = link->priv; -    dev_link_t **linkp; -     +      DEBUG(0, "fmvj18x_detach(0x%p)\n", link); -     -    /* Locate device structure */ -    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) -	if (*linkp == link) break; -    if (*linkp == NULL) -	return;      if (link->dev)  	unregister_netdev(dev); @@ -319,12 +298,6 @@ static void fmvj18x_detach(dev_link_t *link)      if (link->state & DEV_CONFIG)  	fmvj18x_release(link); -    /* Break the link with Card Services */ -    if (link->handle) -	pcmcia_deregister_client(link->handle); -     -    /* Unlink device structure, free pieces */ -    *linkp = link->next;      free_netdev(dev);  } /* fmvj18x_detach */ @@ -713,51 +686,40 @@ static void fmvj18x_release(dev_link_t *link)      link->state &= ~DEV_CONFIG;  } -/*====================================================================*/ - -static int fmvj18x_event(event_t event, int priority, -			  event_callback_args_t *args) +static int fmvj18x_suspend(struct pcmcia_device *p_dev)  { -    dev_link_t *link = args->client_data; -    struct net_device *dev = link->priv; +	dev_link_t *link = dev_to_instance(p_dev); +	struct net_device *dev = link->priv; -    DEBUG(1, "fmvj18x_event(0x%06x)\n", event); -     -    switch (event) { -    case CS_EVENT_CARD_REMOVAL: -	link->state &= ~DEV_PRESENT; -	if (link->state & DEV_CONFIG) -	    netif_device_detach(dev); -	break; -    case CS_EVENT_CARD_INSERTION: -	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; -	fmvj18x_config(link); -	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); +		if (link->open) +			netif_device_detach(dev); +		pcmcia_release_configuration(link->handle);  	} -	break; -    case CS_EVENT_PM_RESUME: + + +	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; -	/* 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); -	    } +		pcmcia_request_configuration(link->handle, &link->conf); +		if (link->open) { +			fjn_reset(dev); +			netif_device_attach(dev); +		}  	} -	break; -    } -    return 0; -} /* fmvj18x_event */ + +	return 0; +} + +/*====================================================================*/  static struct pcmcia_device_id fmvj18x_ids[] = {  	PCMCIA_DEVICE_MANF_CARD(0x0004, 0x0004), @@ -789,10 +751,11 @@ static struct pcmcia_driver fmvj18x_cs_driver = {  	.drv		= {  		.name	= "fmvj18x_cs",  	}, -	.attach		= fmvj18x_attach, -	.event		= fmvj18x_event, -	.detach		= fmvj18x_detach, +	.probe		= fmvj18x_attach, +	.remove		= fmvj18x_detach,  	.id_table       = fmvj18x_ids, +	.suspend	= fmvj18x_suspend, +	.resume		= fmvj18x_resume,  };  static int __init init_fmvj18x_cs(void) @@ -803,7 +766,6 @@ static int __init init_fmvj18x_cs(void)  static void __exit exit_fmvj18x_cs(void)  {  	pcmcia_unregister_driver(&fmvj18x_cs_driver); -	BUG_ON(dev_list != NULL);  }  module_init(init_fmvj18x_cs); diff --git a/drivers/net/pcmcia/ibmtr_cs.c b/drivers/net/pcmcia/ibmtr_cs.c index b6c140eb9799..b9c7e39576f5 100644 --- a/drivers/net/pcmcia/ibmtr_cs.c +++ b/drivers/net/pcmcia/ibmtr_cs.c @@ -108,15 +108,7 @@ MODULE_LICENSE("GPL");  static void ibmtr_config(dev_link_t *link);  static void ibmtr_hw_setup(struct net_device *dev, u_int mmiobase);  static void ibmtr_release(dev_link_t *link); -static int ibmtr_event(event_t event, int priority, -                       event_callback_args_t *args); - -static dev_info_t dev_info = "ibmtr_cs"; - -static dev_link_t *ibmtr_attach(void); -static void ibmtr_detach(dev_link_t *); - -static dev_link_t *dev_list; +static void ibmtr_detach(struct pcmcia_device *p_dev);  /*====================================================================*/ @@ -146,25 +138,23 @@ static struct ethtool_ops netdev_ethtool_ops = {  ======================================================================*/ -static dev_link_t *ibmtr_attach(void) +static int ibmtr_attach(struct pcmcia_device *p_dev)  {      ibmtr_dev_t *info;      dev_link_t *link;      struct net_device *dev; -    client_reg_t client_reg; -    int ret;      DEBUG(0, "ibmtr_attach()\n");      /* Create new token-ring device */      info = kmalloc(sizeof(*info), GFP_KERNEL);  -    if (!info) return NULL; +    if (!info) return -ENOMEM;      memset(info,0,sizeof(*info));      dev = alloc_trdev(sizeof(struct tok_info)); -    if (!dev) {  -	kfree(info);  -	return NULL; -    }  +    if (!dev) { +	kfree(info); +	return -ENOMEM; +    }      link = &info->link;      link->priv = info; @@ -185,25 +175,13 @@ static dev_link_t *ibmtr_attach(void)      SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); -    /* Register with Card Services */ -    link->next = dev_list; -    dev_list = link; -    client_reg.dev_info = &dev_info; -    client_reg.Version = 0x0210; -    client_reg.event_callback_args.client_data = link; -    ret = pcmcia_register_client(&link->handle, &client_reg); -    if (ret != 0) { -        cs_error(link->handle, RegisterClient, ret); -	goto out_detach; -    } +    link->handle = p_dev; +    p_dev->instance = link; -out: -    return link; +    link->state |= DEV_PRESENT; +    ibmtr_config(link); -out_detach: -    ibmtr_detach(link); -    link = NULL; -    goto out; +    return 0;  } /* ibmtr_attach */  /*====================================================================== @@ -215,22 +193,14 @@ out_detach:  ======================================================================*/ -static void ibmtr_detach(dev_link_t *link) +static void ibmtr_detach(struct pcmcia_device *p_dev)  { +    dev_link_t *link = dev_to_instance(p_dev);      struct ibmtr_dev_t *info = link->priv; -    dev_link_t **linkp; -    struct net_device *dev; +    struct net_device *dev = info->dev;      DEBUG(0, "ibmtr_detach(0x%p)\n", link); -    /* Locate device structure */ -    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) -        if (*linkp == link) break; -    if (*linkp == NULL) -        return; - -    dev = info->dev; -      if (link->dev)  	unregister_netdev(dev); @@ -241,13 +211,8 @@ static void ibmtr_detach(dev_link_t *link)      if (link->state & DEV_CONFIG)          ibmtr_release(link); -    if (link->handle) -        pcmcia_deregister_client(link->handle); - -    /* Unlink device structure, free bits */ -    *linkp = link->next;      free_netdev(dev); -    kfree(info);  +    kfree(info);  } /* ibmtr_detach */  /*====================================================================== @@ -401,63 +366,40 @@ static void ibmtr_release(dev_link_t *link)      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; -    The card status event handler.  Mostly, this schedules other -    stuff to run after an event is received.  A CARD_REMOVAL event -    also sets some flags to discourage the net drivers from trying -    to talk to the card any more. +	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_event(event_t event, int priority, -                       event_callback_args_t *args) +static int ibmtr_resume(struct pcmcia_device *p_dev)  { -    dev_link_t *link = args->client_data; -    ibmtr_dev_t *info = link->priv; -    struct net_device *dev = info->dev; +	dev_link_t *link = dev_to_instance(p_dev); +	ibmtr_dev_t *info = link->priv; +	struct net_device *dev = info->dev; -    DEBUG(1, "ibmtr_event(0x%06x)\n", event); - -    switch (event) { -    case CS_EVENT_CARD_REMOVAL: -        link->state &= ~DEV_PRESENT; -        if (link->state & DEV_CONFIG) { -	    /* set flag to bypass normal interrupt code */ -	    struct tok_info *priv = netdev_priv(dev); -	    priv->sram_phys |= 1; -	    netif_device_detach(dev); -        } -        break; -    case CS_EVENT_CARD_INSERTION: -        link->state |= DEV_PRESENT; -	ibmtr_config(link); -	break; -    case CS_EVENT_PM_SUSPEND: -        link->state |= DEV_SUSPEND; -        /* Fall through... */ -    case CS_EVENT_RESET_PHYSICAL: +	link->state &= ~DEV_SUSPEND;          if (link->state & DEV_CONFIG) { -            if (link->open) -		netif_device_detach(dev); -            pcmcia_release_configuration(link->handle); +		pcmcia_request_configuration(link->handle, &link->conf); +		if (link->open) { +			ibmtr_probe(dev);	/* really? */ +			netif_device_attach(dev); +		}          } -        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; -} /* ibmtr_event */ + +	return 0; +} +  /*====================================================================*/ @@ -514,10 +456,11 @@ static struct pcmcia_driver ibmtr_cs_driver = {  	.drv		= {  		.name	= "ibmtr_cs",  	}, -	.attach		= ibmtr_attach, -	.event		= ibmtr_event, -	.detach		= ibmtr_detach, +	.probe		= ibmtr_attach, +	.remove		= ibmtr_detach,  	.id_table       = ibmtr_ids, +	.suspend	= ibmtr_suspend, +	.resume		= ibmtr_resume,  };  static int __init init_ibmtr_cs(void) @@ -528,7 +471,6 @@ static int __init init_ibmtr_cs(void)  static void __exit exit_ibmtr_cs(void)  {  	pcmcia_unregister_driver(&ibmtr_cs_driver); -	BUG_ON(dev_list != NULL);  }  module_init(init_ibmtr_cs); diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c index 980d7e5d66cb..4a232254a497 100644 --- a/drivers/net/pcmcia/nmclan_cs.c +++ b/drivers/net/pcmcia/nmclan_cs.c @@ -388,9 +388,6 @@ static char *version =  DRV_NAME " " DRV_VERSION " (Roger C. Pao)";  #endif -static dev_info_t dev_info="nmclan_cs"; -static dev_link_t *dev_list; -  static char *if_names[]={      "Auto", "10baseT", "BNC",  }; @@ -422,8 +419,6 @@ Function Prototypes  static void nmclan_config(dev_link_t *link);  static void nmclan_release(dev_link_t *link); -static int nmclan_event(event_t event, int priority, -			event_callback_args_t *args);  static void nmclan_reset(struct net_device *dev);  static int mace_config(struct net_device *dev, struct ifmap *map); @@ -439,8 +434,7 @@ static void set_multicast_list(struct net_device *dev);  static struct ethtool_ops netdev_ethtool_ops; -static dev_link_t *nmclan_attach(void); -static void nmclan_detach(dev_link_t *); +static void nmclan_detach(struct pcmcia_device *p_dev);  /* ----------------------------------------------------------------------------  nmclan_attach @@ -449,13 +443,11 @@ nmclan_attach  	Services.  ---------------------------------------------------------------------------- */ -static dev_link_t *nmclan_attach(void) +static int nmclan_attach(struct pcmcia_device *p_dev)  {      mace_private *lp;      dev_link_t *link;      struct net_device *dev; -    client_reg_t client_reg; -    int ret;      DEBUG(0, "nmclan_attach()\n");      DEBUG(1, "%s\n", rcsid); @@ -463,7 +455,7 @@ static dev_link_t *nmclan_attach(void)      /* Create new ethernet device */      dev = alloc_etherdev(sizeof(mace_private));      if (!dev) -	return NULL; +	    return -ENOMEM;      lp = netdev_priv(dev);      link = &lp->link;      link->priv = dev; @@ -497,20 +489,13 @@ static dev_link_t *nmclan_attach(void)      dev->watchdog_timeo = TX_TIMEOUT;  #endif -    /* Register with Card Services */ -    link->next = dev_list; -    dev_list = link; -    client_reg.dev_info = &dev_info; -    client_reg.Version = 0x0210; -    client_reg.event_callback_args.client_data = link; -    ret = pcmcia_register_client(&link->handle, &client_reg); -    if (ret != 0) { -	cs_error(link->handle, RegisterClient, ret); -	nmclan_detach(link); -	return NULL; -    } +    link->handle = p_dev; +    p_dev->instance = link; + +    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; +    nmclan_config(link); -    return link; +    return 0;  } /* nmclan_attach */  /* ---------------------------------------------------------------------------- @@ -521,30 +506,19 @@ nmclan_detach  	when the device is released.  ---------------------------------------------------------------------------- */ -static void nmclan_detach(dev_link_t *link) +static void nmclan_detach(struct pcmcia_device *p_dev)  { +    dev_link_t *link = dev_to_instance(p_dev);      struct net_device *dev = link->priv; -    dev_link_t **linkp;      DEBUG(0, "nmclan_detach(0x%p)\n", link); -    /* Locate device structure */ -    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) -	if (*linkp == link) break; -    if (*linkp == NULL) -	return; -      if (link->dev)  	unregister_netdev(dev);      if (link->state & DEV_CONFIG)  	nmclan_release(link); -    if (link->handle) -	pcmcia_deregister_client(link->handle); - -    /* Unlink device structure, free bits */ -    *linkp = link->next;      free_netdev(dev);  } /* nmclan_detach */ @@ -801,59 +775,39 @@ static void nmclan_release(dev_link_t *link)    link->state &= ~DEV_CONFIG;  } -/* ---------------------------------------------------------------------------- -nmclan_event -	The card status event handler.  Mostly, this schedules other -	stuff to run after an event is received.  A CARD_REMOVAL event -	also sets some flags to discourage the net drivers from trying -	to talk to the card any more. ----------------------------------------------------------------------------- */ -static int nmclan_event(event_t event, int priority, -		       event_callback_args_t *args) +static int nmclan_suspend(struct pcmcia_device *p_dev)  { -  dev_link_t *link = args->client_data; -  struct net_device *dev = link->priv; +	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); +	} -  DEBUG(1, "nmclan_event(0x%06x)\n", event); -  switch (event) { -    case CS_EVENT_CARD_REMOVAL: -      link->state &= ~DEV_PRESENT; -      if (link->state & DEV_CONFIG) -	netif_device_detach(dev); -      break; -    case CS_EVENT_CARD_INSERTION: -      link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; -      nmclan_config(link); -      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); +	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); +		}  	} -      } -      break; -    case CS_EVENT_RESET_REQUEST: -      return 1; -      break; -  } -  return 0; -} /* nmclan_event */ + +	return 0; +} +  /* ----------------------------------------------------------------------------  nmclan_reset @@ -1681,10 +1635,11 @@ static struct pcmcia_driver nmclan_cs_driver = {  	.drv		= {  		.name	= "nmclan_cs",  	}, -	.attach		= nmclan_attach, -	.event		= nmclan_event, -	.detach		= nmclan_detach, +	.probe		= nmclan_attach, +	.remove		= nmclan_detach,  	.id_table       = nmclan_ids, +	.suspend	= nmclan_suspend, +	.resume		= nmclan_resume,  };  static int __init init_nmclan_cs(void) @@ -1695,7 +1650,6 @@ static int __init init_nmclan_cs(void)  static void __exit exit_nmclan_cs(void)  {  	pcmcia_unregister_driver(&nmclan_cs_driver); -	BUG_ON(dev_list != NULL);  }  module_init(init_nmclan_cs); diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index 818c185d6438..d85b758f3efa 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c @@ -105,8 +105,6 @@ module_param_array(hw_addr, int, NULL, 0);  static void mii_phy_probe(struct net_device *dev);  static void pcnet_config(dev_link_t *link);  static void pcnet_release(dev_link_t *link); -static int pcnet_event(event_t event, int priority, -		       event_callback_args_t *args);  static int pcnet_open(struct net_device *dev);  static int pcnet_close(struct net_device *dev);  static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); @@ -120,11 +118,9 @@ static int setup_shmem_window(dev_link_t *link, int start_pg,  static int setup_dma_config(dev_link_t *link, int start_pg,  			    int stop_pg); -static dev_link_t *pcnet_attach(void); -static void pcnet_detach(dev_link_t *); +static void pcnet_detach(struct pcmcia_device *p_dev);  static dev_info_t dev_info = "pcnet_cs"; -static dev_link_t *dev_list;  /*====================================================================*/ @@ -244,19 +240,17 @@ static inline pcnet_dev_t *PRIV(struct net_device *dev)  ======================================================================*/ -static dev_link_t *pcnet_attach(void) +static int pcnet_probe(struct pcmcia_device *p_dev)  {      pcnet_dev_t *info;      dev_link_t *link;      struct net_device *dev; -    client_reg_t client_reg; -    int ret;      DEBUG(0, "pcnet_attach()\n");      /* Create new ethernet device */      dev = __alloc_ei_netdev(sizeof(pcnet_dev_t)); -    if (!dev) return NULL; +    if (!dev) return -ENOMEM;      info = PRIV(dev);      link = &info->link;      link->priv = dev; @@ -271,20 +265,13 @@ static dev_link_t *pcnet_attach(void)      dev->stop = &pcnet_close;      dev->set_config = &set_config; -    /* Register with Card Services */ -    link->next = dev_list; -    dev_list = link; -    client_reg.dev_info = &dev_info; -    client_reg.Version = 0x0210; -    client_reg.event_callback_args.client_data = link; -    ret = pcmcia_register_client(&link->handle, &client_reg); -    if (ret != CS_SUCCESS) { -	cs_error(link->handle, RegisterClient, ret); -	pcnet_detach(link); -	return NULL; -    } +    link->handle = p_dev; +    p_dev->instance = link; -    return link; +    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; +    pcnet_config(link); + +    return 0;  } /* pcnet_attach */  /*====================================================================== @@ -296,31 +283,20 @@ static dev_link_t *pcnet_attach(void)  ======================================================================*/ -static void pcnet_detach(dev_link_t *link) +static void pcnet_detach(struct pcmcia_device *p_dev)  { -    struct net_device *dev = link->priv; -    dev_link_t **linkp; - -    DEBUG(0, "pcnet_detach(0x%p)\n", link); +	dev_link_t *link = dev_to_instance(p_dev); +	struct net_device *dev = link->priv; -    /* Locate device structure */ -    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) -	if (*linkp == link) break; -    if (*linkp == NULL) -	return; +	DEBUG(0, "pcnet_detach(0x%p)\n", link); -    if (link->dev) -	unregister_netdev(dev); +	if (link->dev) +		unregister_netdev(dev); -    if (link->state & DEV_CONFIG) -	pcnet_release(link); - -    if (link->handle) -	pcmcia_deregister_client(link->handle); +	if (link->state & DEV_CONFIG) +		pcnet_release(link); -    /* Unlink device structure, free bits */ -    *linkp = link->next; -    free_netdev(dev); +	free_netdev(dev);  } /* pcnet_detach */  /*====================================================================== @@ -780,50 +756,39 @@ static void pcnet_release(dev_link_t *link)  ======================================================================*/ -static int pcnet_event(event_t event, int priority, -		       event_callback_args_t *args) +static int pcnet_suspend(struct pcmcia_device *p_dev)  { -    dev_link_t *link = args->client_data; -    struct net_device *dev = link->priv; +	dev_link_t *link = dev_to_instance(p_dev); +	struct net_device *dev = link->priv; -    DEBUG(2, "pcnet_event(0x%06x)\n", event); - -    switch (event) { -    case CS_EVENT_CARD_REMOVAL: -	link->state &= ~DEV_PRESENT; -	if (link->state & DEV_CONFIG) -	    netif_device_detach(dev); -	break; -    case CS_EVENT_CARD_INSERTION: -	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; -	pcnet_config(link); -	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); +		if (link->open) +			netif_device_detach(dev); +		pcmcia_release_configuration(link->handle);  	} -	break; -    case CS_EVENT_PM_RESUME: + +	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; -	/* 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); -	    } +		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; -} /* pcnet_event */ + +	return 0; +} +  /*====================================================================== @@ -1844,11 +1809,12 @@ static struct pcmcia_driver pcnet_driver = {  	.drv		= {  		.name	= "pcnet_cs",  	}, -	.attach		= pcnet_attach, -	.event		= pcnet_event, -	.detach		= pcnet_detach, +	.probe		= pcnet_probe, +	.remove		= pcnet_detach,  	.owner		= THIS_MODULE,  	.id_table	= pcnet_ids, +	.suspend	= pcnet_suspend, +	.resume		= pcnet_resume,  };  static int __init init_pcnet_cs(void) @@ -1860,7 +1826,6 @@ static void __exit exit_pcnet_cs(void)  {      DEBUG(0, "pcnet_cs: unloading\n");      pcmcia_unregister_driver(&pcnet_driver); -    BUG_ON(dev_list != NULL);  }  module_init(init_pcnet_cs); diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c index c7cca842e5ee..0122415dfeef 100644 --- a/drivers/net/pcmcia/smc91c92_cs.c +++ b/drivers/net/pcmcia/smc91c92_cs.c @@ -102,10 +102,6 @@ static const char *version =     currently have room for another Tx packet. */  #define MEMORY_WAIT_TIME       	8 -static dev_info_t dev_info = "smc91c92_cs"; - -static dev_link_t *dev_list; -  struct smc_private {      dev_link_t			link;      spinlock_t			lock; @@ -281,12 +277,9 @@ enum RxCfg { RxAllMulti = 0x0004, RxPromisc = 0x0002,  /*====================================================================*/ -static dev_link_t *smc91c92_attach(void); -static void smc91c92_detach(dev_link_t *); +static void smc91c92_detach(struct pcmcia_device *p_dev);  static void smc91c92_config(dev_link_t *link);  static void smc91c92_release(dev_link_t *link); -static int smc91c92_event(event_t event, int priority, -			  event_callback_args_t *args);  static int smc_open(struct net_device *dev);  static int smc_close(struct net_device *dev); @@ -315,20 +308,18 @@ static struct ethtool_ops ethtool_ops;  ======================================================================*/ -static dev_link_t *smc91c92_attach(void) +static int smc91c92_attach(struct pcmcia_device *p_dev)  { -    client_reg_t client_reg;      struct smc_private *smc;      dev_link_t *link;      struct net_device *dev; -    int ret;      DEBUG(0, "smc91c92_attach()\n");      /* Create new ethernet device */      dev = alloc_etherdev(sizeof(struct smc_private));      if (!dev) -	return NULL; +	return -ENOMEM;      smc = netdev_priv(dev);      link = &smc->link;      link->priv = dev; @@ -366,20 +357,13 @@ static dev_link_t *smc91c92_attach(void)      smc->mii_if.phy_id_mask = 0x1f;      smc->mii_if.reg_num_mask = 0x1f; -    /* Register with Card Services */ -    link->next = dev_list; -    dev_list = link; -    client_reg.dev_info = &dev_info; -    client_reg.Version = 0x0210; -    client_reg.event_callback_args.client_data = link; -    ret = pcmcia_register_client(&link->handle, &client_reg); -    if (ret != 0) { -	cs_error(link->handle, RegisterClient, ret); -	smc91c92_detach(link); -	return NULL; -    } +    link->handle = p_dev; +    p_dev->instance = link; + +    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; +    smc91c92_config(link); -    return link; +    return 0;  } /* smc91c92_attach */  /*====================================================================== @@ -391,30 +375,19 @@ static dev_link_t *smc91c92_attach(void)  ======================================================================*/ -static void smc91c92_detach(dev_link_t *link) +static void smc91c92_detach(struct pcmcia_device *p_dev)  { +    dev_link_t *link = dev_to_instance(p_dev);      struct net_device *dev = link->priv; -    dev_link_t **linkp;      DEBUG(0, "smc91c92_detach(0x%p)\n", link); -    /* Locate device structure */ -    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) -	if (*linkp == link) break; -    if (*linkp == NULL) -	return; -      if (link->dev)  	unregister_netdev(dev);      if (link->state & DEV_CONFIG)  	smc91c92_release(link); -    if (link->handle) -	pcmcia_deregister_client(link->handle); - -    /* Unlink device structure, free bits */ -    *linkp = link->next;      free_netdev(dev);  } /* smc91c92_detach */ @@ -895,6 +868,62 @@ free_cfg_mem:     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 @@ -935,14 +964,12 @@ static int check_sig(dev_link_t *link)      }      if (width) { -	event_callback_args_t args;  	printk(KERN_INFO "smc91c92_cs: using 8-bit IO window.\n"); -	args.client_data = link; -	smc91c92_event(CS_EVENT_RESET_PHYSICAL, 0, &args); +	smc91c92_suspend(link->handle);  	pcmcia_release_io(link->handle, &link->io);  	link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;  	pcmcia_request_io(link->handle, &link->io); -	smc91c92_event(CS_EVENT_CARD_RESET, 0, &args); +	smc91c92_resume(link->handle);  	return check_sig(link);      }      return -ENODEV; @@ -1172,82 +1199,6 @@ static void smc91c92_release(dev_link_t *link)  /*====================================================================== -    The card status event handler.  Mostly, this schedules other -    stuff to run after an event is received.  A CARD_REMOVAL event -    also sets some flags to discourage the net drivers from trying -    to talk to the card any more. - -======================================================================*/ - -static int smc91c92_event(event_t event, int priority, -			  event_callback_args_t *args) -{ -    dev_link_t *link = args->client_data; -    struct net_device *dev = link->priv; -    struct smc_private *smc = netdev_priv(dev); -    int i; - -    DEBUG(1, "smc91c92_event(0x%06x)\n", event); - -    switch (event) { -    case CS_EVENT_CARD_REMOVAL: -	link->state &= ~DEV_PRESENT; -	if (link->state & DEV_CONFIG) -	    netif_device_detach(dev); -	break; -    case CS_EVENT_CARD_INSERTION: -	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; -	smc91c92_config(link); -	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; -} /* smc91c92_event */ - -/*====================================================================== -      MII interface support for SMC91cXX based cards  ======================================================================*/ @@ -2360,10 +2311,11 @@ static struct pcmcia_driver smc91c92_cs_driver = {  	.drv		= {  		.name	= "smc91c92_cs",  	}, -	.attach		= smc91c92_attach, -	.event		= smc91c92_event, -	.detach		= smc91c92_detach, +	.probe		= smc91c92_attach, +	.remove		= smc91c92_detach,  	.id_table       = smc91c92_ids, +	.suspend	= smc91c92_suspend, +	.resume		= smc91c92_resume,  };  static int __init init_smc91c92_cs(void) @@ -2374,7 +2326,6 @@ static int __init init_smc91c92_cs(void)  static void __exit exit_smc91c92_cs(void)  {  	pcmcia_unregister_driver(&smc91c92_cs_driver); -	BUG_ON(dev_list != NULL);  }  module_init(init_smc91c92_cs); diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c index ce143f08638a..049c34b37067 100644 --- a/drivers/net/pcmcia/xirc2ps_cs.c +++ b/drivers/net/pcmcia/xirc2ps_cs.c @@ -292,8 +292,6 @@ static void mii_wr(kio_addr_t ioaddr, u_char phyaddr, u_char phyreg,  static int has_ce2_string(dev_link_t * link);  static void xirc2ps_config(dev_link_t * link);  static void xirc2ps_release(dev_link_t * link); -static int xirc2ps_event(event_t event, int priority, -			 event_callback_args_t * args);  /****************   * The attach() and detach() entry points are used to create and destroy @@ -301,8 +299,7 @@ static int xirc2ps_event(event_t event, int priority,   * needed to manage one actual PCMCIA card.   */ -static dev_link_t *xirc2ps_attach(void); -static void xirc2ps_detach(dev_link_t *); +static void xirc2ps_detach(struct pcmcia_device *p_dev);  /****************   * You'll also need to prototype all the functions that will actually @@ -313,14 +310,6 @@ static void xirc2ps_detach(dev_link_t *);  static irqreturn_t xirc2ps_interrupt(int irq, void *dev_id, struct pt_regs *regs); -/* - * The dev_info variable is the "key" that is used to match up this - * device driver with appropriate cards, through the card configuration - * database. - */ - -static dev_info_t dev_info = "xirc2ps_cs"; -  /****************   * A linked list of "instances" of the device.  Each actual   * PCMCIA card corresponds to one device instance, and is described @@ -331,15 +320,7 @@ static dev_info_t dev_info = "xirc2ps_cs";   * device numbers are used to derive the corresponding array index.   */ -static dev_link_t *dev_list; -  /**************** - * A dev_link_t structure has fields for most things that are needed - * to keep track of a socket, but there will usually be some device - * specific information that also needs to be kept track of.  The - * 'priv' pointer in a dev_link_t structure can be used to point to - * a device-specific private data structure, like this. - *   * A driver needs to provide a dev_node_t structure for each device   * on a card.  In some cases, there is only one device per card (for   * example, ethernet cards, modems).  In other cases, there may be @@ -571,21 +552,19 @@ mii_wr(kio_addr_t ioaddr, u_char phyaddr, u_char phyreg, unsigned data, int len)   * card insertion event.   */ -static dev_link_t * -xirc2ps_attach(void) +static int +xirc2ps_attach(struct pcmcia_device *p_dev)  { -    client_reg_t client_reg;      dev_link_t *link;      struct net_device *dev;      local_info_t *local; -    int err;      DEBUG(0, "attach()\n");      /* Allocate the device structure */      dev = alloc_etherdev(sizeof(local_info_t));      if (!dev) -	    return NULL; +	    return -ENOMEM;      local = netdev_priv(dev);      link = &local->link;      link->priv = dev; @@ -614,19 +593,13 @@ xirc2ps_attach(void)      dev->watchdog_timeo = TX_TIMEOUT;  #endif -    /* Register with Card Services */ -    link->next = dev_list; -    dev_list = link; -    client_reg.dev_info = &dev_info; -    client_reg.Version = 0x0210; -    client_reg.event_callback_args.client_data = link; -    if ((err = pcmcia_register_client(&link->handle, &client_reg))) { -	cs_error(link->handle, RegisterClient, err); -	xirc2ps_detach(link); -	return NULL; -    } +    link->handle = p_dev; +    p_dev->instance = link; + +    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; +    xirc2ps_config(link); -    return link; +    return 0;  } /* xirc2ps_attach */  /**************** @@ -637,40 +610,19 @@ xirc2ps_attach(void)   */  static void -xirc2ps_detach(dev_link_t * link) +xirc2ps_detach(struct pcmcia_device *p_dev)  { +    dev_link_t *link = dev_to_instance(p_dev);      struct net_device *dev = link->priv; -    dev_link_t **linkp;      DEBUG(0, "detach(0x%p)\n", link); -    /* Locate device structure */ -    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) -	if (*linkp == link) -	    break; -    if (!*linkp) { -	DEBUG(0, "detach(0x%p): dev_link lost\n", link); -	return; -    } -      if (link->dev)  	unregister_netdev(dev); -    /* -     * If the device is currently configured and active, we won't -     * actually delete it yet.	Instead, it is marked so that when -     * the release() function is called, that will trigger a proper -     * detach(). -     */      if (link->state & DEV_CONFIG)  	xirc2ps_release(link); -    /* Break the link with Card Services */ -    if (link->handle) -	pcmcia_deregister_client(link->handle); - -    /* Unlink device structure, free it */ -    *linkp = link->next;      free_netdev(dev);  } /* xirc2ps_detach */ @@ -1157,67 +1109,41 @@ xirc2ps_release(dev_link_t *link)  /*====================================================================*/ -/**************** - * The card status event handler.  Mostly, this schedules other - * stuff to run after an event is received.  A CARD_REMOVAL event - * also sets some flags to discourage the net drivers from trying - * to talk to the card any more. - * - * When a CARD_REMOVAL event is received, we immediately set a flag - * to block future accesses to this device.  All the functions that - * actually access the device should check this flag to make sure - * the card is still present. - */ -static int -xirc2ps_event(event_t event, int priority, -	      event_callback_args_t * args) +static int xirc2ps_suspend(struct pcmcia_device *p_dev)  { -    dev_link_t *link = args->client_data; -    struct net_device *dev = link->priv; - -    DEBUG(0, "event(%d)\n", (int)event); +	dev_link_t *link = dev_to_instance(p_dev); +	struct net_device *dev = link->priv; -    switch (event) { -    case CS_EVENT_REGISTRATION_COMPLETE: -	DEBUG(0, "registration complete\n"); -	break; -    case CS_EVENT_CARD_REMOVAL: -	link->state &= ~DEV_PRESENT; -	if (link->state & DEV_CONFIG) -	    netif_device_detach(dev); -	break; -    case CS_EVENT_CARD_INSERTION: -	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; -	xirc2ps_config(link); -	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); +		if (link->open) { +			netif_device_detach(dev); +			do_powerdown(dev); +		} +		pcmcia_release_configuration(link->handle);  	} -	break; -    case CS_EVENT_PM_RESUME: + +	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; -	/* 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); -	    } +		pcmcia_request_configuration(link->handle, &link->conf); +		if (link->open) { +			do_reset(dev,1); +			netif_device_attach(dev); +		}  	} -	break; -    } -    return 0; -} /* xirc2ps_event */ + +	return 0; +} +  /*====================================================================*/ @@ -2009,10 +1935,11 @@ static struct pcmcia_driver xirc2ps_cs_driver = {  	.drv		= {  		.name	= "xirc2ps_cs",  	}, -	.attach		= xirc2ps_attach, -	.event		= xirc2ps_event, -	.detach		= xirc2ps_detach, +	.probe		= xirc2ps_attach, +	.remove		= xirc2ps_detach,  	.id_table       = xirc2ps_ids, +	.suspend	= xirc2ps_suspend, +	.resume		= xirc2ps_resume,  };  static int __init @@ -2025,7 +1952,6 @@ static void __exit  exit_xirc2ps_cs(void)  {  	pcmcia_unregister_driver(&xirc2ps_cs_driver); -	BUG_ON(dev_list != NULL);  }  module_init(init_xirc2ps_cs); diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c index e328547599dc..a496460ce224 100644 --- a/drivers/net/wireless/airo_cs.c +++ b/drivers/net/wireless/airo_cs.c @@ -82,8 +82,6 @@ MODULE_SUPPORTED_DEVICE("Aironet 4500, 4800 and Cisco 340 PCMCIA cards");  static void airo_config(dev_link_t *link);  static void airo_release(dev_link_t *link); -static int airo_event(event_t event, int priority, -		       event_callback_args_t *args);  /*     The attach() and detach() entry points are used to create and destroy @@ -91,8 +89,7 @@ static int airo_event(event_t event, int priority,     needed to manage one actual PCMCIA card.  */ -static dev_link_t *airo_attach(void); -static void airo_detach(dev_link_t *); +static void airo_detach(struct pcmcia_device *p_dev);  /*     You'll also need to prototype all the functions that will actually @@ -102,14 +99,6 @@ static void airo_detach(dev_link_t *);  */  /* -   The dev_info variable is the "key" that is used to match up this -   device driver with appropriate cards, through the card configuration -   database. -*/ - -static dev_info_t dev_info = "airo_cs"; - -/*     A linked list of "instances" of the  aironet device.  Each actual     PCMCIA card corresponds to one device instance, and is described     by one dev_link_t structure (defined in ds.h). @@ -119,15 +108,7 @@ static dev_info_t dev_info = "airo_cs";     device numbers are used to derive the corresponding array index.  */ -static dev_link_t *dev_list = NULL; -  /* -   A dev_link_t structure has fields for most things that are needed -   to keep track of a socket, but there will usually be some device -   specific information that also needs to be kept track of.  The -   'priv' pointer in a dev_link_t structure can be used to point to -   a device-specific private data structure, like this. -     A driver needs to provide a dev_node_t structure for each device     on a card.  In some cases, there is only one device per card (for     example, ethernet cards, modems).  In other cases, there may be @@ -160,20 +141,18 @@ typedef struct local_info_t {    ======================================================================*/ -static dev_link_t *airo_attach(void) +static int airo_attach(struct pcmcia_device *p_dev)  { -	client_reg_t client_reg;  	dev_link_t *link;  	local_info_t *local; -	int ret; -	 +  	DEBUG(0, "airo_attach()\n");  	/* Initialize the dev_link_t structure */  	link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL);  	if (!link) {  		printk(KERN_ERR "airo_cs: no memory for new device\n"); -		return NULL; +		return -ENOMEM;  	}  	/* Interrupt setup */ @@ -197,24 +176,17 @@ static dev_link_t *airo_attach(void)  	if (!local) {  		printk(KERN_ERR "airo_cs: no memory for new device\n");  		kfree (link); -		return NULL; +		return -ENOMEM;  	}  	link->priv = local; -	 -	/* Register with Card Services */ -	link->next = dev_list; -	dev_list = link; -	client_reg.dev_info = &dev_info; -	client_reg.Version = 0x0210; -	client_reg.event_callback_args.client_data = link; -	ret = pcmcia_register_client(&link->handle, &client_reg); -	if (ret != 0) { -		cs_error(link->handle, RegisterClient, ret); -		airo_detach(link); -		return NULL; -	} -	 -	return link; + +	link->handle = p_dev; +	p_dev->instance = link; + +	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; +	airo_config(link); + +	return 0;  } /* airo_attach */  /*====================================================================== @@ -226,37 +198,22 @@ static dev_link_t *airo_attach(void)    ======================================================================*/ -static void airo_detach(dev_link_t *link) +static void airo_detach(struct pcmcia_device *p_dev)  { -	dev_link_t **linkp; -	 +	dev_link_t *link = dev_to_instance(p_dev); +  	DEBUG(0, "airo_detach(0x%p)\n", link); -	 -	/* Locate device structure */ -	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) -		if (*linkp == link) break; -	if (*linkp == NULL) -		return; -	 +  	if (link->state & DEV_CONFIG)  		airo_release(link); -	 +  	if ( ((local_info_t*)link->priv)->eth_dev ) {  		stop_airo_card( ((local_info_t*)link->priv)->eth_dev, 0 );  	} -	((local_info_t*)link->priv)->eth_dev = NULL;    -	 -	/* Break the link with Card Services */ -	if (link->handle) -		pcmcia_deregister_client(link->handle); -	 -	 -	 -	/* Unlink device structure, free pieces */ -	*linkp = link->next; +	((local_info_t*)link->priv)->eth_dev = NULL; +  	kfree(link->priv);  	kfree(link); -	  } /* airo_detach */  /*====================================================================== @@ -492,60 +449,34 @@ static void airo_release(dev_link_t *link)  	link->state &= ~DEV_CONFIG;  } -/*====================================================================== -   -  The card status event handler.  Mostly, this schedules other -  stuff to run after an event is received. +static int airo_suspend(struct pcmcia_device *p_dev) +{ +	dev_link_t *link = dev_to_instance(p_dev); +	local_info_t *local = link->priv; -  When a CARD_REMOVAL event is received, we immediately set a -  private flag to block future accesses to this device.  All the -  functions that actually access the device should check this flag -  to make sure the card is still present. -   -  ======================================================================*/ +	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_event(event_t event, int priority, -		      event_callback_args_t *args) +static int airo_resume(struct pcmcia_device *p_dev)  { -	dev_link_t *link = args->client_data; +	dev_link_t *link = dev_to_instance(p_dev);  	local_info_t *local = link->priv; -	 -	DEBUG(1, "airo_event(0x%06x)\n", event); -	 -	switch (event) { -	case CS_EVENT_CARD_REMOVAL: -		link->state &= ~DEV_PRESENT; -		if (link->state & DEV_CONFIG) { -			netif_device_detach(local->eth_dev); -			airo_release(link); -		} -		break; -	case CS_EVENT_CARD_INSERTION: -		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; -		airo_config(link); -		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; + +	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; -} /* airo_event */ +}  static struct pcmcia_device_id airo_ids[] = {  	PCMCIA_DEVICE_MANF_CARD(0x015f, 0x000a), @@ -561,10 +492,11 @@ static struct pcmcia_driver airo_driver = {  	.drv		= {  		.name	= "airo_cs",  	}, -	.attach		= airo_attach, -	.event		= airo_event, -	.detach		= airo_detach, +	.probe		= airo_attach, +	.remove		= airo_detach,  	.id_table       = airo_ids, +	.suspend	= airo_suspend, +	.resume		= airo_resume,  };  static int airo_cs_init(void) @@ -575,7 +507,6 @@ static int airo_cs_init(void)  static void airo_cs_cleanup(void)  {  	pcmcia_unregister_driver(&airo_driver); -	BUG_ON(dev_list != NULL);  }  /* diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c index 17d1fd90f832..d6f4a5a3e55a 100644 --- a/drivers/net/wireless/atmel_cs.c +++ b/drivers/net/wireless/atmel_cs.c @@ -93,8 +93,6 @@ MODULE_SUPPORTED_DEVICE("Atmel at76c50x PCMCIA cards");  static void atmel_config(dev_link_t *link);  static void atmel_release(dev_link_t *link); -static int atmel_event(event_t event, int priority, -		       event_callback_args_t *args);  /*     The attach() and detach() entry points are used to create and destroy @@ -102,8 +100,7 @@ static int atmel_event(event_t event, int priority,     needed to manage one actual PCMCIA card.  */ -static dev_link_t *atmel_attach(void); -static void atmel_detach(dev_link_t *); +static void atmel_detach(struct pcmcia_device *p_dev);  /*     You'll also need to prototype all the functions that will actually @@ -113,14 +110,6 @@ static void atmel_detach(dev_link_t *);  */  /* -   The dev_info variable is the "key" that is used to match up this -   device driver with appropriate cards, through the card configuration -   database. -*/ - -static dev_info_t dev_info = "atmel_cs"; - -/*     A linked list of "instances" of the  atmelnet device.  Each actual     PCMCIA card corresponds to one device instance, and is described     by one dev_link_t structure (defined in ds.h). @@ -130,15 +119,7 @@ static dev_info_t dev_info = "atmel_cs";     device numbers are used to derive the corresponding array index.  */ -static dev_link_t *dev_list = NULL; -  /* -   A dev_link_t structure has fields for most things that are needed -   to keep track of a socket, but there will usually be some device -   specific information that also needs to be kept track of.  The -   'priv' pointer in a dev_link_t structure can be used to point to -   a device-specific private data structure, like this. -     A driver needs to provide a dev_node_t structure for each device     on a card.  In some cases, there is only one device per card (for     example, ethernet cards, modems).  In other cases, there may be @@ -171,27 +152,25 @@ typedef struct local_info_t {    ======================================================================*/ -static dev_link_t *atmel_attach(void) +static int atmel_attach(struct pcmcia_device *p_dev)  { -	client_reg_t client_reg;  	dev_link_t *link;  	local_info_t *local; -	int ret; -	 +  	DEBUG(0, "atmel_attach()\n");  	/* Initialize the dev_link_t structure */  	link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL);  	if (!link) {  		printk(KERN_ERR "atmel_cs: no memory for new device\n"); -		return NULL; +		return -ENOMEM;  	} -	 +  	/* Interrupt setup */  	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;  	link->irq.IRQInfo1 = IRQ_LEVEL_ID;  	link->irq.Handler = NULL; -	 +  	/*  	  General socket configuration defaults can go here.  In this  	  client, we assume very little, and rely on the CIS for almost @@ -202,30 +181,23 @@ static dev_link_t *atmel_attach(void)  	link->conf.Attributes = 0;  	link->conf.Vcc = 50;  	link->conf.IntType = INT_MEMORY_AND_IO; -	 +  	/* Allocate space for private device-specific data */  	local = kzalloc(sizeof(local_info_t), GFP_KERNEL);  	if (!local) {  		printk(KERN_ERR "atmel_cs: no memory for new device\n");  		kfree (link); -		return NULL; +		return -ENOMEM;  	}  	link->priv = local; -	 -	/* Register with Card Services */ -	link->next = dev_list; -	dev_list = link; -	client_reg.dev_info = &dev_info; -	client_reg.Version = 0x0210; -	client_reg.event_callback_args.client_data = link; -	ret = pcmcia_register_client(&link->handle, &client_reg); -	if (ret != 0) { -		cs_error(link->handle, RegisterClient, ret); -		atmel_detach(link); -		return NULL; -	} -	 -	return link; + +	link->handle = p_dev; +	p_dev->instance = link; + +	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; +	atmel_config(link); + +	return 0;  } /* atmel_attach */  /*====================================================================== @@ -237,27 +209,15 @@ static dev_link_t *atmel_attach(void)    ======================================================================*/ -static void atmel_detach(dev_link_t *link) +static void atmel_detach(struct pcmcia_device *p_dev)  { -	dev_link_t **linkp; -	 +	dev_link_t *link = dev_to_instance(p_dev); +  	DEBUG(0, "atmel_detach(0x%p)\n", link); -	 -	/* Locate device structure */ -	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) -		if (*linkp == link) break; -	if (*linkp == NULL) -		return;  	if (link->state & DEV_CONFIG)  		atmel_release(link); -		 -	/* Break the link with Card Services */ -	if (link->handle) -		pcmcia_deregister_client(link->handle); -	/* Unlink device structure, free pieces */ -	*linkp = link->next;  	kfree(link->priv);  	kfree(link);  } @@ -477,60 +437,34 @@ static void atmel_release(dev_link_t *link)  	link->state &= ~DEV_CONFIG;  } -/*====================================================================== -   -  The card status event handler.  Mostly, this schedules other -  stuff to run after an event is received. +static int atmel_suspend(struct pcmcia_device *dev) +{ +	dev_link_t *link = dev_to_instance(dev); +	local_info_t *local = link->priv; -  When a CARD_REMOVAL event is received, we immediately set a -  private flag to block future accesses to this device.  All the -  functions that actually access the device should check this flag -  to make sure the card is still present. -   -  ======================================================================*/ +	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_event(event_t event, int priority, -		      event_callback_args_t *args) +static int atmel_resume(struct pcmcia_device *dev)  { -	dev_link_t *link = args->client_data; +	dev_link_t *link = dev_to_instance(dev);  	local_info_t *local = link->priv; -	 -	DEBUG(1, "atmel_event(0x%06x)\n", event); -	 -	switch (event) { -	case CS_EVENT_CARD_REMOVAL: -		link->state &= ~DEV_PRESENT; -		if (link->state & DEV_CONFIG) { -			netif_device_detach(local->eth_dev); -			atmel_release(link); -		} -		break; -	case CS_EVENT_CARD_INSERTION: -		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; -		atmel_config(link); -		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; + +	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; -} /* atmel_event */ +}  /*====================================================================*/  /* We use the driver_info field to store the correct firmware type for a card. */ @@ -581,10 +515,11 @@ static struct pcmcia_driver atmel_driver = {  	.drv		= {  		.name	= "atmel_cs",          }, -	.attach         = atmel_attach, -	.event		= atmel_event, -	.detach		= atmel_detach, +	.probe          = atmel_attach, +	.remove		= atmel_detach,  	.id_table	= atmel_ids, +	.suspend	= atmel_suspend, +	.resume		= atmel_resume,  };  static int atmel_cs_init(void) @@ -595,7 +530,6 @@ static int atmel_cs_init(void)  static void atmel_cs_cleanup(void)  {          pcmcia_unregister_driver(&atmel_driver); -	BUG_ON(dev_list != NULL);  }  /* diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c index 2643976a6677..8bc0b528548f 100644 --- a/drivers/net/wireless/hostap/hostap_cs.c +++ b/drivers/net/wireless/hostap/hostap_cs.c @@ -25,7 +25,6 @@  static char *version = PRISM2_VERSION " (Jouni Malinen <jkmaline@cc.hut.fi>)";  static dev_info_t dev_info = "hostap_cs"; -static dev_link_t *dev_list = NULL;  MODULE_AUTHOR("Jouni Malinen");  MODULE_DESCRIPTION("Support for Intersil Prism2-based 802.11 wireless LAN " @@ -203,10 +202,9 @@ static int hfa384x_to_bap(struct net_device *dev, u16 bap, void *buf, int len) -static void prism2_detach(dev_link_t *link); +static void prism2_detach(struct pcmcia_device *p_dev);  static void prism2_release(u_long arg); -static int prism2_event(event_t event, int priority, -			event_callback_args_t *args); +static int prism2_config(dev_link_t *link);  static int prism2_pccard_card_present(local_info_t *local) @@ -503,15 +501,13 @@ static struct prism2_helper_functions prism2_pccard_funcs =  /* allocate local data and register with CardServices   * initialize dev_link structure, but do not configure the card yet */ -static dev_link_t *prism2_attach(void) +static int prism2_attach(struct pcmcia_device *p_dev)  {  	dev_link_t *link; -	client_reg_t client_reg; -	int ret;  	link = kmalloc(sizeof(dev_link_t), GFP_KERNEL);  	if (link == NULL) -		return NULL; +		return -ENOMEM;  	memset(link, 0, sizeof(dev_link_t)); @@ -519,50 +515,27 @@ static dev_link_t *prism2_attach(void)  	link->conf.Vcc = 33;  	link->conf.IntType = INT_MEMORY_AND_IO; -	/* register with CardServices */ -	link->next = dev_list; -	dev_list = link; -	client_reg.dev_info = &dev_info; -	client_reg.Version = 0x0210; -	client_reg.event_callback_args.client_data = link; -	ret = pcmcia_register_client(&link->handle, &client_reg); -	if (ret != CS_SUCCESS) { -		cs_error(link->handle, RegisterClient, ret); -		prism2_detach(link); -		return NULL; -	} -	return link; +	link->handle = p_dev; +	p_dev->instance = link; + +	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; +	if (prism2_config(link)) +		PDEBUG(DEBUG_EXTRA, "prism2_config() failed\n"); + +	return 0;  } -static void prism2_detach(dev_link_t *link) +static void prism2_detach(struct pcmcia_device *p_dev)  { -	dev_link_t **linkp; +	dev_link_t *link = dev_to_instance(p_dev);  	PDEBUG(DEBUG_FLOW, "prism2_detach\n"); -	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) -		if (*linkp == link) -			break; -	if (*linkp == NULL) { -		printk(KERN_WARNING "%s: Attempt to detach non-existing " -		       "PCMCIA client\n", dev_info); -		return; -	} -  	if (link->state & DEV_CONFIG) {  		prism2_release((u_long)link);  	} -	if (link->handle) { -		int res = pcmcia_deregister_client(link->handle); -		if (res) { -			printk("CardService(DeregisterClient) => %d\n", res); -			cs_error(link->handle, DeregisterClient, res); -		} -	} - -	*linkp = link->next;  	/* release net devices */  	if (link->priv) {  		struct hostap_cs_priv *hw_priv; @@ -846,84 +819,58 @@ static void prism2_release(u_long arg)  	PDEBUG(DEBUG_FLOW, "release - done\n");  } - -static int prism2_event(event_t event, int priority, -			event_callback_args_t *args) +static int hostap_cs_suspend(struct pcmcia_device *p_dev)  { -	dev_link_t *link = args->client_data; +	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; -	} - -	switch (event) { -	case CS_EVENT_CARD_INSERTION: -		PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_CARD_INSERTION\n", dev_info); -		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; -		if (prism2_config(link)) { -			PDEBUG(DEBUG_EXTRA, "prism2_config() failed\n"); -		} -		break; - -	case CS_EVENT_CARD_REMOVAL: -		PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_CARD_REMOVAL\n", dev_info); -		link->state &= ~DEV_PRESENT; -		if (link->state & DEV_CONFIG) { +		if (dev_open) {  			netif_stop_queue(dev);  			netif_device_detach(dev); -			prism2_release((u_long) link);  		} -		break; +		prism2_suspend(dev); +		pcmcia_release_configuration(link->handle); +	} -	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; +	return 0; +} -	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; +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; -	default: -		PDEBUG(DEBUG_EXTRA, "%s: prism2_event() - unknown event %d\n", -		       dev_info, event); -		break; +	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 struct pcmcia_device_id hostap_cs_ids[] = {  	PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7100),  	PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7300), @@ -982,11 +929,12 @@ static struct pcmcia_driver hostap_driver = {  	.drv		= {  		.name	= "hostap_cs",  	}, -	.attach		= prism2_attach, -	.detach		= prism2_detach, +	.probe		= prism2_attach, +	.remove		= prism2_detach,  	.owner		= THIS_MODULE, -	.event		= prism2_event,  	.id_table	= hostap_cs_ids, +	.suspend	= hostap_cs_suspend, +	.resume		= hostap_cs_resume,  };  static int __init init_prism2_pccard(void) diff --git a/drivers/net/wireless/netwave_cs.c b/drivers/net/wireless/netwave_cs.c index 92793b958e32..bf6271ee387a 100644 --- a/drivers/net/wireless/netwave_cs.c +++ b/drivers/net/wireless/netwave_cs.c @@ -166,8 +166,6 @@ static char *version =  #define DEBUG(n, args...)  #endif -static dev_info_t dev_info = "netwave_cs"; -  /*====================================================================*/  /* Parameters that can be set with 'insmod' */ @@ -195,12 +193,9 @@ module_param(mem_speed, int, 0);  /* PCMCIA (Card Services) related functions */  static void netwave_release(dev_link_t *link);     /* Card removal */ -static int  netwave_event(event_t event, int priority,  -					      event_callback_args_t *args);  static void netwave_pcmcia_config(dev_link_t *arg); /* Runs after card   													   insertion */ -static dev_link_t *netwave_attach(void);     /* Create instance */ -static void netwave_detach(dev_link_t *);    /* Destroy instance */ +static void netwave_detach(struct pcmcia_device *p_dev);    /* Destroy instance */  /* Hardware configuration */  static void netwave_doreset(kio_addr_t iobase, u_char __iomem *ramBase); @@ -228,17 +223,6 @@ static struct iw_statistics* netwave_get_wireless_stats(struct net_device *dev);  static void set_multicast_list(struct net_device *dev);  /* -   A linked list of "instances" of the skeleton device.  Each actual -   PCMCIA card corresponds to one device instance, and is described -   by one dev_link_t structure (defined in ds.h). - -   You may not want to use a linked list for this -- for example, the -   memory card driver uses an array of dev_link_t pointers, where minor -   device numbers are used to derive the corresponding array index. -*/ -static dev_link_t *dev_list; - -/*     A dev_link_t structure has fields for most things that are needed     to keep track of a socket, but there will usually be some device     specific information that also needs to be kept track of.  The @@ -394,20 +378,18 @@ static struct iw_statistics *netwave_get_wireless_stats(struct net_device *dev)   *     configure the card at this point -- we wait until we receive a   *     card insertion event.   */ -static dev_link_t *netwave_attach(void) +static int netwave_attach(struct pcmcia_device *p_dev)  { -    client_reg_t client_reg;      dev_link_t *link;      struct net_device *dev;      netwave_private *priv; -    int ret; -     +      DEBUG(0, "netwave_attach()\n"); -     +      /* Initialize the dev_link_t structure */      dev = alloc_etherdev(sizeof(netwave_private));      if (!dev) -	return NULL; +	return -ENOMEM;      priv = netdev_priv(dev);      link = &priv->link;      link->priv = dev; @@ -449,21 +431,14 @@ static dev_link_t *netwave_attach(void)      dev->open = &netwave_open;      dev->stop = &netwave_close;      link->irq.Instance = dev; -     -    /* Register with Card Services */ -    link->next = dev_list; -    dev_list = link; -    client_reg.dev_info = &dev_info; -    client_reg.Version = 0x0210; -    client_reg.event_callback_args.client_data = link; -    ret = pcmcia_register_client(&link->handle, &client_reg); -    if (ret != 0) { -	cs_error(link->handle, RegisterClient, ret); -	netwave_detach(link); -	return NULL; -    } -    return link; +    link->handle = p_dev; +    p_dev->instance = link; + +    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; +    netwave_pcmcia_config( link); + +    return 0;  } /* netwave_attach */  /* @@ -474,42 +449,20 @@ static dev_link_t *netwave_attach(void)   *    structures are freed.  Otherwise, the structures will be freed   *    when the device is released.   */ -static void netwave_detach(dev_link_t *link) +static void netwave_detach(struct pcmcia_device *p_dev)  { -    struct net_device *dev = link->priv; -    dev_link_t **linkp; +	dev_link_t *link = dev_to_instance(p_dev); +	struct net_device *dev = link->priv; -    DEBUG(0, "netwave_detach(0x%p)\n", link); -   -    /* -	  If the device is currently configured and active, we won't -	  actually delete it yet.  Instead, it is marked so that when -	  the release() function is called, that will trigger a proper -	  detach(). -	*/ -    if (link->state & DEV_CONFIG) -	netwave_release(link); -	 -    /* Break the link with Card Services */ -    if (link->handle) -	pcmcia_deregister_client(link->handle); -     -    /* Locate device structure */ -    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) -	if (*linkp == link) break; -    if (*linkp == NULL) -      { -	DEBUG(1, "netwave_cs: detach fail, '%s' not in list\n", -	      link->dev->dev_name); -	return; -      } - -    /* Unlink device structure, free pieces */ -    *linkp = link->next; -    if (link->dev)  -	unregister_netdev(dev); -    free_netdev(dev); -     +	DEBUG(0, "netwave_detach(0x%p)\n", link); + +	if (link->state & DEV_CONFIG) +		netwave_release(link); + +	if (link->dev) +		unregister_netdev(dev); + +	free_netdev(dev);  } /* netwave_detach */  /* @@ -935,69 +888,38 @@ static void netwave_release(dev_link_t *link)      link->state &= ~DEV_CONFIG;  } -/* - * Function netwave_event (event, priority, args) - * - *    The card status event handler.  Mostly, this schedules other - *    stuff to run after an event is received.  A CARD_REMOVAL event - *    also sets some flags to discourage the net drivers from trying - *    to talk to the card any more. - * - *    When a CARD_REMOVAL event is received, we immediately set a flag - *    to block future accesses to this device.  All the functions that - *    actually access the device should check this flag to make sure - *    the card is still present. - * - */ -static int netwave_event(event_t event, int priority, -			 event_callback_args_t *args) +static int netwave_suspend(struct pcmcia_device *p_dev)  { -    dev_link_t *link = args->client_data; -    struct net_device *dev = link->priv; -	 -    DEBUG(1, "netwave_event(0x%06x)\n", event); -   -    switch (event) { -    case CS_EVENT_REGISTRATION_COMPLETE: -	DEBUG(0, "netwave_cs: registration complete\n"); -	break; - -    case CS_EVENT_CARD_REMOVAL: -	link->state &= ~DEV_PRESENT; -	if (link->state & DEV_CONFIG) { -	    netif_device_detach(dev); -	    netwave_release(link); -	} -	break; -    case CS_EVENT_CARD_INSERTION: -	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; -	netwave_pcmcia_config( link); -	break; -    case CS_EVENT_PM_SUSPEND: +	dev_link_t *link = dev_to_instance(p_dev); +	struct net_device *dev = link->priv; +  	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); +		if (link->open) +			netif_device_detach(dev); +		pcmcia_release_configuration(link->handle);  	} -	break; -    case CS_EVENT_PM_RESUME: + +	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; -	/* 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); -	    } +		pcmcia_request_configuration(link->handle, &link->conf); +		if (link->open) { +			netwave_reset(dev); +			netif_device_attach(dev); +		}  	} -	break; -    } -    return 0; -} /* netwave_event */ + +	return 0; +} +  /*   * Function netwave_doreset (ioBase, ramBase) @@ -1491,10 +1413,11 @@ static struct pcmcia_driver netwave_driver = {  	.drv		= {  		.name	= "netwave_cs",  	}, -	.attach		= netwave_attach, -	.event		= netwave_event, -	.detach		= netwave_detach, +	.probe		= netwave_attach, +	.remove		= netwave_detach,  	.id_table       = netwave_ids, +	.suspend	= netwave_suspend, +	.resume		= netwave_resume,  };  static int __init init_netwave_cs(void) @@ -1505,7 +1428,6 @@ static int __init init_netwave_cs(void)  static void __exit exit_netwave_cs(void)  {  	pcmcia_unregister_driver(&netwave_driver); -	BUG_ON(dev_list != NULL);  }  module_init(init_netwave_cs); diff --git a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c index dc1128a00971..b664708481cc 100644 --- a/drivers/net/wireless/orinoco_cs.c +++ b/drivers/net/wireless/orinoco_cs.c @@ -43,17 +43,6 @@ module_param(ignore_cis_vcc, int, 0);  MODULE_PARM_DESC(ignore_cis_vcc, "Allow voltage mismatch between card and socket");  /********************************************************************/ -/* Magic constants						    */ -/********************************************************************/ - -/* - * The dev_info variable is the "key" that is used to match up this - * device driver with appropriate cards, through the card - * configuration database. - */ -static dev_info_t dev_info = DRIVER_NAME; - -/********************************************************************/  /* Data structures						    */  /********************************************************************/ @@ -69,19 +58,14 @@ struct orinoco_pccard {  	unsigned long hard_reset_in_progress;   }; -/* - * A linked list of "instances" of the device.  Each actual PCMCIA - * card corresponds to one device instance, and is described by one - * dev_link_t structure (defined in ds.h). - */ -static dev_link_t *dev_list; /* = NULL */  /********************************************************************/  /* Function prototypes						    */  /********************************************************************/ +static void orinoco_cs_config(dev_link_t *link);  static void orinoco_cs_release(dev_link_t *link); -static void orinoco_cs_detach(dev_link_t *link); +static void orinoco_cs_detach(struct pcmcia_device *p_dev);  /********************************************************************/  /* Device methods     						    */ @@ -119,19 +103,17 @@ orinoco_cs_hard_reset(struct orinoco_private *priv)   * The dev_link structure is initialized, but we don't actually   * configure the card at this point -- we wait until we receive a card   * insertion event.  */ -static dev_link_t * -orinoco_cs_attach(void) +static int +orinoco_cs_attach(struct pcmcia_device *p_dev)  {  	struct net_device *dev;  	struct orinoco_private *priv;  	struct orinoco_pccard *card;  	dev_link_t *link; -	client_reg_t client_reg; -	int ret;  	dev = alloc_orinocodev(sizeof(*card), orinoco_cs_hard_reset);  	if (! dev) -		return NULL; +		return -ENOMEM;  	priv = netdev_priv(dev);  	card = priv->card; @@ -154,22 +136,15 @@ orinoco_cs_attach(void)  	link->conf.IntType = INT_MEMORY_AND_IO;  	/* Register with Card Services */ -	/* FIXME: need a lock? */ -	link->next = dev_list; -	dev_list = link; - -	client_reg.dev_info = &dev_info; -	client_reg.Version = 0x0210; /* FIXME: what does this mean? */ -	client_reg.event_callback_args.client_data = link; - -	ret = pcmcia_register_client(&link->handle, &client_reg); -	if (ret != CS_SUCCESS) { -		cs_error(link->handle, RegisterClient, ret); -		orinoco_cs_detach(link); -		return NULL; -	} +	link->next = NULL; + +	link->handle = p_dev; +	p_dev->instance = link; + +	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; +	orinoco_cs_config(link); -	return link; +	return 0;  }				/* orinoco_cs_attach */  /* @@ -178,27 +153,14 @@ orinoco_cs_attach(void)   * are freed.  Otherwise, the structures will be freed when the device   * is released.   */ -static void orinoco_cs_detach(dev_link_t *link) +static void orinoco_cs_detach(struct pcmcia_device *p_dev)  { -	dev_link_t **linkp; +	dev_link_t *link = dev_to_instance(p_dev);  	struct net_device *dev = link->priv; -	/* Locate device structure */ -	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) -		if (*linkp == link) -			break; - -	BUG_ON(*linkp == NULL); -  	if (link->state & DEV_CONFIG)  		orinoco_cs_release(link); -	/* Break the link with Card Services */ -	if (link->handle) -		pcmcia_deregister_client(link->handle); - -	/* Unlink device structure, and free it */ -	*linkp = link->next;  	DEBUG(0, PFX "detach: link=%p link->dev=%p\n", link, link->dev);  	if (link->dev) {  		DEBUG(0, PFX "About to unregister net device %p\n", @@ -465,106 +427,82 @@ orinoco_cs_release(dev_link_t *link)  		ioport_unmap(priv->hw.iobase);  }				/* orinoco_cs_release */ -/* - * The card status event handler.  Mostly, this schedules other stuff - * to run after an event is received. - */ -static int -orinoco_cs_event(event_t event, int priority, -		       event_callback_args_t * args) +static int orinoco_cs_suspend(struct pcmcia_device *p_dev)  { -	dev_link_t *link = args->client_data; +	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; -	switch (event) { -	case CS_EVENT_CARD_REMOVAL: -		link->state &= ~DEV_PRESENT; -		if (link->state & DEV_CONFIG) { -			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);  		} -		break; -	case CS_EVENT_CARD_INSERTION: -		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; -		orinoco_cs_config(link); -		break; +		pcmcia_release_configuration(link->handle); +	} -	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); +	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;  			} -			pcmcia_release_configuration(link->handle); -		} -		break; +			spin_lock_irqsave(&priv->lock, flags); + +			netif_device_attach(dev); +			priv->hw_unavailable--; -	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", +			if (priv->open && ! priv->hw_unavailable) { +				err = __orinoco_up(dev); +				if (err) +					printk(KERN_ERR "%s: Error %d restarting card\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);  			} + +			spin_unlock_irqrestore(&priv->lock, flags);  		} -		break;  	} -	return err; -}				/* orinoco_cs_event */ +	return 0; +} +  /********************************************************************/  /* Module initialization					    */ @@ -665,10 +603,11 @@ static struct pcmcia_driver orinoco_driver = {  	.drv		= {  		.name	= DRIVER_NAME,  	}, -	.attach		= orinoco_cs_attach, -	.detach		= orinoco_cs_detach, -	.event		= orinoco_cs_event, +	.probe		= orinoco_cs_attach, +	.remove		= orinoco_cs_detach,  	.id_table       = orinoco_cs_ids, +	.suspend	= orinoco_cs_suspend, +	.resume		= orinoco_cs_resume,  };  static int __init @@ -683,7 +622,6 @@ static void __exit  exit_orinoco_cs(void)  {  	pcmcia_unregister_driver(&orinoco_driver); -	BUG_ON(dev_list != NULL);  }  module_init(init_orinoco_cs); diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c index 70fd6fd8feb9..319180ca7e71 100644 --- a/drivers/net/wireless/ray_cs.c +++ b/drivers/net/wireless/ray_cs.c @@ -92,9 +92,7 @@ module_param(pc_debug, int, 0);  /** Prototypes based on PCMCIA skeleton driver *******************************/  static void ray_config(dev_link_t *link);  static void ray_release(dev_link_t *link); -static int ray_event(event_t event, int priority, event_callback_args_t *args); -static dev_link_t *ray_attach(void); -static void ray_detach(dev_link_t *); +static void ray_detach(struct pcmcia_device *p_dev);  /***** Prototypes indicated by device structure ******************************/  static int ray_dev_close(struct net_device *dev); @@ -192,12 +190,6 @@ static int bc;  static char *phy_addr = NULL; -/* The dev_info variable is the "key" that is used to match up this -   device driver with appropriate cards, through the card configuration -   database. -*/ -static dev_info_t dev_info = "ray_cs"; -  /* A linked list of "instances" of the ray device.  Each actual     PCMCIA card corresponds to one device instance, and is described     by one dev_link_t structure (defined in ds.h). @@ -314,12 +306,10 @@ static char rcsid[] = "Raylink/WebGear wireless LAN - Corey <Thomas corey@world.      configure the card at this point -- we wait until we receive a      card insertion event.  =============================================================================*/ -static dev_link_t *ray_attach(void) +static int ray_attach(struct pcmcia_device *p_dev)  { -    client_reg_t client_reg;      dev_link_t *link;      ray_dev_t *local; -    int ret;      struct net_device *dev;      DEBUG(1, "ray_attach()\n"); @@ -328,7 +318,7 @@ static dev_link_t *ray_attach(void)      link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);      if (!link) -	    return NULL; +	    return -ENOMEM;      /* Allocate space for private device-specific data */      dev = alloc_etherdev(sizeof(ray_dev_t)); @@ -387,30 +377,19 @@ static dev_link_t *ray_attach(void)      dev->stop = &ray_dev_close;      netif_stop_queue(dev); -    /* Register with Card Services */ -    link->next = dev_list; -    dev_list = link; -    client_reg.dev_info = &dev_info; -    client_reg.Version = 0x0210; -    client_reg.event_callback_args.client_data = link; +    init_timer(&local->timer); -    DEBUG(2,"ray_cs ray_attach calling pcmcia_register_client(...)\n"); +    link->handle = p_dev; +    p_dev->instance = link; -    init_timer(&local->timer); +    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; +    ray_config(link); -    ret = pcmcia_register_client(&link->handle, &client_reg); -    if (ret != 0) { -        printk("ray_cs ray_attach RegisterClient unhappy - detaching\n"); -        cs_error(link->handle, RegisterClient, ret); -        ray_detach(link); -        return NULL; -    } -    DEBUG(2,"ray_cs ray_attach ending\n"); -    return link; +    return 0;  fail_alloc_dev:      kfree(link); -    return NULL; +    return -ENOMEM;  } /* ray_attach */  /*=============================================================================      This deletes a driver "instance".  The device is de-registered @@ -418,9 +397,12 @@ fail_alloc_dev:      structures are freed.  Otherwise, the structures will be freed      when the device is released.  =============================================================================*/ -static void ray_detach(dev_link_t *link) +static void ray_detach(struct pcmcia_device *p_dev)  { +    dev_link_t *link = dev_to_instance(p_dev);      dev_link_t **linkp; +    struct net_device *dev; +    ray_dev_t *local;      DEBUG(1, "ray_detach(0x%p)\n", link); @@ -430,22 +412,18 @@ static void ray_detach(dev_link_t *link)      if (*linkp == NULL)          return; -    /* If the device is currently configured and active, we won't -      actually delete it yet.  Instead, it is marked so that when -      the release() function is called, that will trigger a proper -      detach(). -    */ -    if (link->state & DEV_CONFIG) -        ray_release(link); +    dev = link->priv; + +    if (link->state & DEV_CONFIG) { +	    ray_release(link); + +	    local = (ray_dev_t *)dev->priv; +            del_timer(&local->timer); +    } -    /* Break the link with Card Services */ -    if (link->handle) -        pcmcia_deregister_client(link->handle); -          /* Unlink device structure, free pieces */      *linkp = link->next;      if (link->priv) { -        struct net_device *dev = link->priv;  	if (link->dev) unregister_netdev(dev);          free_netdev(dev);      } @@ -891,65 +869,40 @@ static void ray_release(dev_link_t *link)      DEBUG(2,"ray_release ending\n");  } -/*============================================================================= -    The card status event handler.  Mostly, this schedules other -    stuff to run after an event is received.  A CARD_REMOVAL event -    also sets some flags to discourage the net drivers from trying -    to talk to the card any more. - -    When a CARD_REMOVAL event is received, we immediately set a flag -    to block future accesses to this device.  All the functions that -    actually access the device should check this flag to make sure -    the card is still present. -=============================================================================*/ -static int ray_event(event_t event, int priority, -                     event_callback_args_t *args) +static int ray_suspend(struct pcmcia_device *p_dev)  { -    dev_link_t *link = args->client_data; -    struct net_device *dev = link->priv; -    ray_dev_t *local = (ray_dev_t *)dev->priv; -    DEBUG(1, "ray_event(0x%06x)\n", event); -     -    switch (event) { -    case CS_EVENT_CARD_REMOVAL: -        link->state &= ~DEV_PRESENT; -        netif_device_detach(dev); -        if (link->state & DEV_CONFIG) { -	    ray_release(link); -            del_timer(&local->timer); -        } -        break; -    case CS_EVENT_CARD_INSERTION: -        link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; -        ray_config(link); -        break; -    case CS_EVENT_PM_SUSPEND: -        link->state |= DEV_SUSPEND; -        /* Fall through... */ -    case CS_EVENT_RESET_PHYSICAL: +	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); +		if (link->open) +			netif_device_detach(dev); -            pcmcia_release_configuration(link->handle); +		pcmcia_release_configuration(link->handle);          } -        break; -    case CS_EVENT_PM_RESUME: -        link->state &= ~DEV_SUSPEND; -        /* Fall through... */ -    case CS_EVENT_CARD_RESET: + + +	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); -            } +		pcmcia_request_configuration(link->handle, &link->conf); +		if (link->open) { +			ray_reset(dev); +			netif_device_attach(dev); +		}          } -        break; -    } -    return 0; -    DEBUG(2,"ray_event ending\n"); -} /* ray_event */ + +	return 0; +} +  /*===========================================================================*/  int ray_dev_init(struct net_device *dev)  { @@ -2945,10 +2898,11 @@ static struct pcmcia_driver ray_driver = {  	.drv		= {  		.name	= "ray_cs",  	}, -	.attach		= ray_attach, -	.event		= ray_event, -	.detach		= ray_detach, +	.probe		= ray_attach, +	.remove		= ray_detach,  	.id_table       = ray_ids, +	.suspend	= ray_suspend, +	.resume		= ray_resume,  };  static int __init init_ray_cs(void) diff --git a/drivers/net/wireless/spectrum_cs.c b/drivers/net/wireless/spectrum_cs.c index b1bbc8e8e91f..fee4be1ce810 100644 --- a/drivers/net/wireless/spectrum_cs.c +++ b/drivers/net/wireless/spectrum_cs.c @@ -57,17 +57,6 @@ module_param(ignore_cis_vcc, int, 0);  MODULE_PARM_DESC(ignore_cis_vcc, "Allow voltage mismatch between card and socket");  /********************************************************************/ -/* Magic constants						    */ -/********************************************************************/ - -/* - * The dev_info variable is the "key" that is used to match up this - * device driver with appropriate cards, through the card - * configuration database. - */ -static dev_info_t dev_info = DRIVER_NAME; - -/********************************************************************/  /* Data structures						    */  /********************************************************************/ @@ -78,19 +67,12 @@ struct orinoco_pccard {  	dev_node_t node;  }; -/* - * A linked list of "instances" of the device.  Each actual PCMCIA - * card corresponds to one device instance, and is described by one - * dev_link_t structure (defined in ds.h). - */ -static dev_link_t *dev_list; /* = NULL */ -  /********************************************************************/  /* Function prototypes						    */  /********************************************************************/ +static void spectrum_cs_config(dev_link_t *link);  static void spectrum_cs_release(dev_link_t *link); -static void spectrum_cs_detach(dev_link_t *link);  /********************************************************************/  /* Firmware downloader						    */ @@ -601,19 +583,17 @@ spectrum_cs_hard_reset(struct orinoco_private *priv)   * The dev_link structure is initialized, but we don't actually   * configure the card at this point -- we wait until we receive a card   * insertion event.  */ -static dev_link_t * -spectrum_cs_attach(void) +static int +spectrum_cs_attach(struct pcmcia_device *p_dev)  {  	struct net_device *dev;  	struct orinoco_private *priv;  	struct orinoco_pccard *card;  	dev_link_t *link; -	client_reg_t client_reg; -	int ret;  	dev = alloc_orinocodev(sizeof(*card), spectrum_cs_hard_reset);  	if (! dev) -		return NULL; +		return -ENOMEM;  	priv = netdev_priv(dev);  	card = priv->card; @@ -635,23 +615,13 @@ spectrum_cs_attach(void)  	link->conf.Attributes = 0;  	link->conf.IntType = INT_MEMORY_AND_IO; -	/* Register with Card Services */ -	/* FIXME: need a lock? */ -	link->next = dev_list; -	dev_list = link; +	link->handle = p_dev; +	p_dev->instance = link; -	client_reg.dev_info = &dev_info; -	client_reg.Version = 0x0210; /* FIXME: what does this mean? */ -	client_reg.event_callback_args.client_data = link; +	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; +	spectrum_cs_config(link); -	ret = pcmcia_register_client(&link->handle, &client_reg); -	if (ret != CS_SUCCESS) { -		cs_error(link->handle, RegisterClient, ret); -		spectrum_cs_detach(link); -		return NULL; -	} - -	return link; +	return 0;  }				/* spectrum_cs_attach */  /* @@ -660,27 +630,14 @@ spectrum_cs_attach(void)   * are freed.  Otherwise, the structures will be freed when the device   * is released.   */ -static void spectrum_cs_detach(dev_link_t *link) +static void spectrum_cs_detach(struct pcmcia_device *p_dev)  { -	dev_link_t **linkp; +	dev_link_t *link = dev_to_instance(p_dev);  	struct net_device *dev = link->priv; -	/* Locate device structure */ -	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) -		if (*linkp == link) -			break; - -	BUG_ON(*linkp == NULL); -  	if (link->state & DEV_CONFIG)  		spectrum_cs_release(link); -	/* Break the link with Card Services */ -	if (link->handle) -		pcmcia_deregister_client(link->handle); - -	/* Unlink device structure, and free it */ -	*linkp = link->next;  	DEBUG(0, PFX "detach: link=%p link->dev=%p\n", link, link->dev);  	if (link->dev) {  		DEBUG(0, PFX "About to unregister net device %p\n", @@ -948,82 +905,56 @@ spectrum_cs_release(dev_link_t *link)  		ioport_unmap(priv->hw.iobase);  }				/* spectrum_cs_release */ -/* - * The card status event handler.  Mostly, this schedules other stuff - * to run after an event is received. - */ +  static int -spectrum_cs_event(event_t event, int priority, -		       event_callback_args_t * args) +spectrum_cs_suspend(struct pcmcia_device *p_dev)  { -	dev_link_t *link = args->client_data; +	dev_link_t *link = dev_to_instance(p_dev);  	struct net_device *dev = link->priv;  	struct orinoco_private *priv = netdev_priv(dev); -	int err = 0;  	unsigned long flags; +	int err = 0; -	switch (event) { -	case CS_EVENT_CARD_REMOVAL: -		link->state &= ~DEV_PRESENT; -		if (link->state & DEV_CONFIG) { -			unsigned long flags; +	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); -			spin_lock_irqsave(&priv->lock, flags); -			netif_device_detach(dev); -			priv->hw_unavailable++; -			spin_unlock_irqrestore(&priv->lock, flags); -		} -		break; +		err = __orinoco_down(dev); +		if (err) +			printk(KERN_WARNING "%s: Error %d downing interface\n", +			       dev->name, err); -	case CS_EVENT_CARD_INSERTION: -		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; -		spectrum_cs_config(link); -		break; +		netif_device_detach(dev); +		priv->hw_unavailable++; -	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; +		spin_unlock_irqrestore(&priv->lock, flags); -	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; +		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; +} -	return err; -}				/* spectrum_cs_event */  /********************************************************************/  /* Module initialization					    */ @@ -1048,9 +979,10 @@ static struct pcmcia_driver orinoco_driver = {  	.drv		= {  		.name	= DRIVER_NAME,  	}, -	.attach		= spectrum_cs_attach, -	.detach		= spectrum_cs_detach, -	.event		= spectrum_cs_event, +	.probe		= spectrum_cs_attach, +	.remove		= spectrum_cs_detach, +	.suspend	= spectrum_cs_suspend, +	.resume		= spectrum_cs_resume,  	.id_table       = spectrum_cs_ids,  }; @@ -1066,7 +998,6 @@ static void __exit  exit_spectrum_cs(void)  {  	pcmcia_unregister_driver(&orinoco_driver); -	BUG_ON(dev_list != NULL);  }  module_init(init_spectrum_cs); diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c index c822cad3333f..7e2039f52c49 100644 --- a/drivers/net/wireless/wavelan_cs.c +++ b/drivers/net/wireless/wavelan_cs.c @@ -4594,14 +4594,12 @@ wavelan_close(struct net_device *	dev)   * configure the card at this point -- we wait until we receive a   * card insertion event.   */ -static dev_link_t * -wavelan_attach(void) +static int +wavelan_attach(struct pcmcia_device *p_dev)  { -  client_reg_t	client_reg;	/* Register with cardmgr */    dev_link_t *	link;		/* Info for cardmgr */    struct net_device *	dev;		/* Interface generic data */    net_local *	lp;		/* Interface specific data */ -  int		ret;  #ifdef DEBUG_CALLBACK_TRACE    printk(KERN_DEBUG "-> wavelan_attach()\n"); @@ -4609,7 +4607,7 @@ wavelan_attach(void)    /* Initialize the dev_link_t structure */    link = kzalloc(sizeof(struct dev_link_t), GFP_KERNEL); -  if (!link) return NULL; +  if (!link) return -ENOMEM;    /* The io structure describes IO port mapping */    link->io.NumPorts1 = 8; @@ -4627,14 +4625,13 @@ wavelan_attach(void)    link->conf.IntType = INT_MEMORY_AND_IO;    /* Chain drivers */ -  link->next = dev_list; -  dev_list = link; +  link->next = NULL;    /* Allocate the generic data structure */    dev = alloc_etherdev(sizeof(net_local));    if (!dev) {        kfree(link); -      return NULL; +      return -ENOMEM;    }    link->priv = link->irq.Instance = dev; @@ -4679,28 +4676,21 @@ wavelan_attach(void)    /* Other specific data */    dev->mtu = WAVELAN_MTU; -  /* Register with Card Services */ -  client_reg.dev_info = &dev_info; -  client_reg.Version = 0x0210; -  client_reg.event_callback_args.client_data = link; +  link->handle = p_dev; +  p_dev->instance = link; -#ifdef DEBUG_CONFIG_INFO -  printk(KERN_DEBUG "wavelan_attach(): almost done, calling pcmcia_register_client\n"); -#endif - -  ret = pcmcia_register_client(&link->handle, &client_reg); -  if(ret != 0) -    { -      cs_error(link->handle, RegisterClient, ret); -      wavelan_detach(link); -      return NULL; -    } +  link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; +  if(wv_pcmcia_config(link) && +     wv_hw_config(dev)) +	  wv_init_info(dev); +  else +	  dev->irq = 0;  #ifdef DEBUG_CALLBACK_TRACE    printk(KERN_DEBUG "<- wavelan_attach()\n");  #endif -  return link; +  return 0;  }  /*------------------------------------------------------------------*/ @@ -4711,8 +4701,10 @@ wavelan_attach(void)   * is released.   */  static void -wavelan_detach(dev_link_t *	link) +wavelan_detach(struct pcmcia_device *p_dev)  { +   dev_link_t *link = dev_to_instance(p_dev); +  #ifdef DEBUG_CALLBACK_TRACE    printk(KERN_DEBUG "-> wavelan_detach(0x%p)\n", link);  #endif @@ -4729,31 +4721,6 @@ wavelan_detach(dev_link_t *	link)        wv_pcmcia_release(link);      } -  /* Break the link with Card Services */ -  if(link->handle) -    pcmcia_deregister_client(link->handle); -     -  /* Remove the interface data from the linked list */ -  if(dev_list == link) -    dev_list = link->next; -  else -    { -      dev_link_t *	prev = dev_list; - -      while((prev != (dev_link_t *) NULL) && (prev->next != link)) -	prev = prev->next; - -      if(prev == (dev_link_t *) NULL) -	{ -#ifdef DEBUG_CONFIG_ERRORS -	  printk(KERN_WARNING "wavelan_detach : Attempting to remove a nonexistent device.\n"); -#endif -	  return; -	} - -      prev->next = link->next; -    } -    /* Free pieces */    if(link->priv)      { @@ -4775,65 +4742,11 @@ wavelan_detach(dev_link_t *	link)  #endif  } -/*------------------------------------------------------------------*/ -/* - * The card status event handler. Mostly, this schedules other stuff - * to run after an event is received. A CARD_REMOVAL event also sets - * some flags to discourage the net drivers from trying to talk to the - * card any more. - */ -static int -wavelan_event(event_t		event,		/* The event received */ -	      int		priority, -	      event_callback_args_t *	args) +static int wavelan_suspend(struct pcmcia_device *p_dev)  { -  dev_link_t *	link = (dev_link_t *) args->client_data; -  struct net_device *	dev = (struct net_device *) link->priv; - -#ifdef DEBUG_CALLBACK_TRACE -  printk(KERN_DEBUG "->wavelan_event(): %s\n", -	 ((event == CS_EVENT_REGISTRATION_COMPLETE)?"registration complete" : -	  ((event == CS_EVENT_CARD_REMOVAL) ? "card removal" : -	   ((event == CS_EVENT_CARD_INSERTION) ? "card insertion" : -	    ((event == CS_EVENT_PM_SUSPEND) ? "pm suspend" : -	     ((event == CS_EVENT_RESET_PHYSICAL) ? "physical reset" : -	      ((event == CS_EVENT_PM_RESUME) ? "pm resume" : -	       ((event == CS_EVENT_CARD_RESET) ? "card reset" : -		"unknown")))))))); -#endif - -    switch(event) -      { -      case CS_EVENT_REGISTRATION_COMPLETE: -#ifdef DEBUG_CONFIG_INFO -	printk(KERN_DEBUG "wavelan_cs: registration complete\n"); -#endif -	break; +	dev_link_t *link = dev_to_instance(p_dev); +	struct net_device *	dev = (struct net_device *) link->priv; -      case CS_EVENT_CARD_REMOVAL: -	/* Oups ! The card is no more there */ -	link->state &= ~DEV_PRESENT; -	if(link->state & DEV_CONFIG) -	  { -	    /* Accept no more transmissions */ -	    netif_device_detach(dev); - -	    /* Release the card */ -	    wv_pcmcia_release(link); -	  } -	break; - -      case CS_EVENT_CARD_INSERTION: -	/* Reset and configure the card */ -	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; -	if(wv_pcmcia_config(link) && -	   wv_hw_config(dev)) -	  wv_init_info(dev); -	else -	  dev->irq = 0; -	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, @@ -4848,38 +4761,37 @@ wavelan_event(event_t		event,		/* The event received */  	/* 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; +	{ +		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; -      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; -    } +	{ +		pcmcia_request_configuration(link->handle, &link->conf); +		if(link->open)	/* If RESET -> True, If RESUME -> False ? */ +		{ +			wv_hw_reset(dev); +			netif_device_attach(dev); +		} +	} -#ifdef DEBUG_CALLBACK_TRACE -  printk(KERN_DEBUG "<-wavelan_event()\n"); -#endif -  return 0; +	return 0;  } +  static struct pcmcia_device_id wavelan_ids[] = {  	PCMCIA_DEVICE_PROD_ID12("AT&T","WaveLAN/PCMCIA", 0xe7c5affd, 0x1bc50975),  	PCMCIA_DEVICE_PROD_ID12("Digital", "RoamAbout/DS", 0x9999ab35, 0x00d05e06), @@ -4894,10 +4806,11 @@ static struct pcmcia_driver wavelan_driver = {  	.drv		= {  		.name	= "wavelan_cs",  	}, -	.attach		= wavelan_attach, -	.event		= wavelan_event, -	.detach		= wavelan_detach, +	.probe		= wavelan_attach, +	.remove		= wavelan_detach,  	.id_table       = wavelan_ids, +	.suspend	= wavelan_suspend, +	.resume		= wavelan_resume,  };  static int __init diff --git a/drivers/net/wireless/wavelan_cs.p.h b/drivers/net/wireless/wavelan_cs.p.h index 724a715089c9..f2d597568151 100644 --- a/drivers/net/wireless/wavelan_cs.p.h +++ b/drivers/net/wireless/wavelan_cs.p.h @@ -754,20 +754,11 @@ static void  static int  	wavelan_open(struct net_device *),		/* Open the device */  	wavelan_close(struct net_device *);	/* Close the device */ -static dev_link_t * -	wavelan_attach(void);		/* Create a new device */  static void -	wavelan_detach(dev_link_t *);	/* Destroy a removed device */ -static int -	wavelan_event(event_t,		/* Manage pcmcia events */ -		      int, -		      event_callback_args_t *); +	wavelan_detach(struct pcmcia_device *p_dev);	/* Destroy a removed device */  /**************************** VARIABLES ****************************/ -static dev_info_t dev_info = "wavelan_cs"; -static dev_link_t *dev_list = NULL;	/* Linked list of devices */ -  /*   * Parameters that can be set with 'insmod'   * The exact syntax is 'insmod wavelan_cs.o <var>=<value>' diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c index 978fdc606781..48e10b0c7e74 100644 --- a/drivers/net/wireless/wl3501_cs.c +++ b/drivers/net/wireless/wl3501_cs.c @@ -105,7 +105,6 @@ module_param(pc_debug, int, 0);   */  static void wl3501_config(dev_link_t *link);  static void wl3501_release(dev_link_t *link); -static int wl3501_event(event_t event, int pri, event_callback_args_t *args);  /*   * The dev_info variable is the "key" that is used to match up this @@ -1498,9 +1497,11 @@ static struct ethtool_ops ops = {   * Services. If it has been released, all local data structures are freed.   * Otherwise, the structures will be freed when the device is released.   */ -static void wl3501_detach(dev_link_t *link) +static void wl3501_detach(struct pcmcia_device *p_dev)  { +	dev_link_t *link = dev_to_instance(p_dev);  	dev_link_t **linkp; +	struct net_device *dev = link->priv;  	/* Locate device structure */  	for (linkp = &wl3501_dev_list; *linkp; linkp = &(*linkp)->next) @@ -1514,16 +1515,12 @@ static void wl3501_detach(dev_link_t *link)  	 * function is called, that will trigger a proper detach(). */  	if (link->state & DEV_CONFIG) { -#ifdef PCMCIA_DEBUG -		printk(KERN_DEBUG "wl3501_cs: detach postponed, '%s' " -		       "still locked\n", link->dev->dev_name); -#endif -		goto out; -	} +		while (link->open > 0) +			wl3501_close(dev); -	/* Break the link with Card Services */ -	if (link->handle) -		pcmcia_deregister_client(link->handle); +		netif_device_detach(dev); +		wl3501_release(link); +	}  	/* Unlink device structure, free pieces */  	*linkp = link->next; @@ -1956,18 +1953,16 @@ static const struct iw_handler_def wl3501_handler_def = {   * The dev_link structure is initialized, but we don't actually configure the   * card at this point -- we wait until we receive a card insertion event.   */ -static dev_link_t *wl3501_attach(void) +static int wl3501_attach(struct pcmcia_device *p_dev)  { -	client_reg_t client_reg;  	dev_link_t *link;  	struct net_device *dev;  	struct wl3501_card *this; -	int ret;  	/* Initialize the dev_link_t structure */  	link = kzalloc(sizeof(*link), GFP_KERNEL);  	if (!link) -		goto out; +		return -ENOMEM;  	/* The io structure describes IO port mapping */  	link->io.NumPorts1	= 16; @@ -2003,24 +1998,17 @@ static dev_link_t *wl3501_attach(void)  	netif_stop_queue(dev);  	link->priv = link->irq.Instance = dev; -	/* Register with Card Services */ -	link->next		 = wl3501_dev_list; -	wl3501_dev_list		 = link; -	client_reg.dev_info	 = &wl3501_dev_info; -	client_reg.Version	 = 0x0210; -	client_reg.event_callback_args.client_data = link; -	ret = pcmcia_register_client(&link->handle, &client_reg); -	if (ret) { -		cs_error(link->handle, RegisterClient, ret); -		wl3501_detach(link); -		link = NULL; -	} -out: -	return link; +	link->handle = p_dev; +	p_dev->instance = link; + +	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; +	wl3501_config(link); + +	return 0;  out_link:  	kfree(link);  	link = NULL; -	goto out; +	return -ENOMEM;  }  #define CS_CHECK(fn, ret) \ @@ -2173,67 +2161,41 @@ static void wl3501_release(dev_link_t *link)  	link->state &= ~DEV_CONFIG;  } -/** - * wl3501_event - The card status event handler - * @event - event - * @pri - priority - * @args - arguments for this event - * - * The card status event handler. Mostly, this schedules other stuff to run - * after an event is received. A CARD_REMOVAL event also sets some flags to - * discourage the net drivers from trying to talk to the card any more. - * - * When a CARD_REMOVAL event is received, we immediately set a flag to block - * future accesses to this device. All the functions that actually access the - * device should check this flag to make sure the card is still present. - */ -static int wl3501_event(event_t event, int pri, event_callback_args_t *args) +static int wl3501_suspend(struct pcmcia_device *p_dev)  { -	dev_link_t *link = args->client_data; +	dev_link_t *link = dev_to_instance(p_dev);  	struct net_device *dev = link->priv; -	switch (event) { -	case CS_EVENT_CARD_REMOVAL: -		link->state &= ~DEV_PRESENT; -		if (link->state & DEV_CONFIG) { -			while (link->open > 0) -				wl3501_close(dev); +	link->state |= DEV_SUSPEND; + +	wl3501_pwr_mgmt(dev->priv, WL3501_SUSPEND); +	if (link->state & DEV_CONFIG) { +		if (link->open)  			netif_device_detach(dev); -			wl3501_release(link); -		} -		break; -	case CS_EVENT_CARD_INSERTION: -		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; -		wl3501_config(link); -		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); -			} +		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);  		} -		break;  	} +  	return 0;  } +  static struct pcmcia_device_id wl3501_ids[] = {  	PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0001),  	PCMCIA_DEVICE_NULL @@ -2245,10 +2207,11 @@ static struct pcmcia_driver wl3501_driver = {  	.drv		= {  		.name	= "wl3501_cs",  	}, -	.attach		= wl3501_attach, -	.event		= wl3501_event, -	.detach		= wl3501_detach, +	.probe		= wl3501_attach, +	.remove		= wl3501_detach,  	.id_table	= wl3501_ids, +	.suspend	= wl3501_suspend, +	.resume		= wl3501_resume,  };  static int __init wl3501_init_module(void) diff --git a/drivers/parport/parport_cs.c b/drivers/parport/parport_cs.c index 24e6aacddb74..158d92563259 100644 --- a/drivers/parport/parport_cs.c +++ b/drivers/parport/parport_cs.c @@ -87,15 +87,9 @@ typedef struct parport_info_t {      struct parport	*port;  } parport_info_t; -static dev_link_t *parport_attach(void); -static void parport_detach(dev_link_t *); +static void parport_detach(struct pcmcia_device *p_dev);  static void parport_config(dev_link_t *link);  static void parport_cs_release(dev_link_t *); -static int parport_event(event_t event, int priority, -			 event_callback_args_t *args); - -static dev_info_t dev_info = "parport_cs"; -static dev_link_t *dev_list = NULL;  /*====================================================================== @@ -105,18 +99,16 @@ static dev_link_t *dev_list = NULL;  ======================================================================*/ -static dev_link_t *parport_attach(void) +static int parport_attach(struct pcmcia_device *p_dev)  {      parport_info_t *info;      dev_link_t *link; -    client_reg_t client_reg; -    int ret; -     +      DEBUG(0, "parport_attach()\n");      /* Create new parport device */      info = kmalloc(sizeof(*info), GFP_KERNEL); -    if (!info) return NULL; +    if (!info) return -ENOMEM;      memset(info, 0, sizeof(*info));      link = &info->link; link->priv = info; @@ -127,21 +119,14 @@ static dev_link_t *parport_attach(void)      link->conf.Attributes = CONF_ENABLE_IRQ;      link->conf.Vcc = 50;      link->conf.IntType = INT_MEMORY_AND_IO; -     -    /* Register with Card Services */ -    link->next = dev_list; -    dev_list = link; -    client_reg.dev_info = &dev_info; -    client_reg.Version = 0x0210; -    client_reg.event_callback_args.client_data = link; -    ret = pcmcia_register_client(&link->handle, &client_reg); -    if (ret != CS_SUCCESS) { -	cs_error(link->handle, RegisterClient, ret); -	parport_detach(link); -	return NULL; -    } -     -    return link; + +    link->handle = p_dev; +    p_dev->instance = link; + +    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; +    parport_config(link); + +    return 0;  } /* parport_attach */  /*====================================================================== @@ -153,32 +138,16 @@ static dev_link_t *parport_attach(void)  ======================================================================*/ -static void parport_detach(dev_link_t *link) +static void parport_detach(struct pcmcia_device *p_dev)  { -    dev_link_t **linkp; -    int ret; +    dev_link_t *link = dev_to_instance(p_dev);      DEBUG(0, "parport_detach(0x%p)\n", link); -     -    /* Locate device structure */ -    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) -	if (*linkp == link) break; -    if (*linkp == NULL) -	return;      if (link->state & DEV_CONFIG)  	parport_cs_release(link); -     -    if (link->handle) { -	ret = pcmcia_deregister_client(link->handle); -	if (ret != CS_SUCCESS) -	    cs_error(link->handle, DeregisterClient, ret); -    } -     -    /* Unlink, free device structure */ -    *linkp = link->next; +      kfree(link->priv); -      } /* parport_detach */  /*====================================================================== @@ -325,47 +294,27 @@ void parport_cs_release(dev_link_t *link)  } /* parport_cs_release */ -/*====================================================================== - -    The card status event handler.  Mostly, this schedules other -    stuff to run after an event is received. -     -======================================================================*/ - -int parport_event(event_t event, int priority, -		  event_callback_args_t *args) +static int parport_suspend(struct pcmcia_device *dev)  { -    dev_link_t *link = args->client_data; +	dev_link_t *link = dev_to_instance(dev); -    DEBUG(1, "parport_event(0x%06x)\n", event); -     -    switch (event) { -    case CS_EVENT_CARD_REMOVAL: -	link->state &= ~DEV_PRESENT; -	if (link->state & DEV_CONFIG) -		parport_cs_release(link); -	break; -    case CS_EVENT_CARD_INSERTION: -	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; -	parport_config(link); -	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: +		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; -	/* Fall through... */ -    case CS_EVENT_CARD_RESET:  	if (DEV_OK(link)) -	    pcmcia_request_configuration(link->handle, &link->conf); -	break; -    } -    return 0; -} /* parport_event */ +		pcmcia_request_configuration(link->handle, &link->conf); + +	return 0; +}  static struct pcmcia_device_id parport_ids[] = {  	PCMCIA_DEVICE_FUNC_ID(3), @@ -379,11 +328,11 @@ static struct pcmcia_driver parport_cs_driver = {  	.drv		= {  		.name	= "parport_cs",  	}, -	.attach		= parport_attach, -	.event		= parport_event, -	.detach		= parport_detach, +	.probe		= parport_attach, +	.remove		= parport_detach,  	.id_table	= parport_ids, - +	.suspend	= parport_suspend, +	.resume		= parport_resume,  };  static int __init init_parport_cs(void) @@ -394,7 +343,6 @@ static int __init init_parport_cs(void)  static void __exit exit_parport_cs(void)  {  	pcmcia_unregister_driver(&parport_cs_driver); -	BUG_ON(dev_list != NULL);  }  module_init(init_parport_cs); diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig index 309eb557f9a3..1f4ad0e7836e 100644 --- a/drivers/pcmcia/Kconfig +++ b/drivers/pcmcia/Kconfig @@ -116,6 +116,31 @@ config YENTA  	  If unsure, say Y. +config YENTA_O2 +	default y +	bool "Special initialization for O2Micro bridges" if EMBEDDED +	depends on YENTA + +config YENTA_RICOH +	default y +	bool "Special initialization for Ricoh bridges" if EMBEDDED +	depends on YENTA + +config YENTA_TI +	default y +	bool "Special initialization for TI and EnE bridges" if EMBEDDED +	depends on YENTA + +config YENTA_ENE_TUNE +	default y +	bool "Auto-tune EnE bridges for CB cards" if EMBEDDED +	depends on YENTA_TI && CARDBUS + +config YENTA_TOSHIBA +	default y +	bool "Special initialization for Toshiba ToPIC bridges" if EMBEDDED +	depends on YENTA +  config PD6729  	tristate "Cirrus PD6729 compatible bridge support"  	depends on PCMCIA && PCI @@ -157,7 +182,7 @@ config TCIC  config PCMCIA_M8XX          tristate "MPC8xx PCMCIA support"          depends on PCMCIA && PPC && 8xx  -        select PCCARD_NONSTATIC +        select PCCARD_IODYN          help          Say Y here to include support for PowerPC 8xx series PCMCIA          controller. @@ -200,7 +225,7 @@ config PCMCIA_PXA2XX  config PCMCIA_PROBE  	bool -	default y if ISA && !ARCH_SA1100 && !ARCH_CLPS711X +	default y if ISA && !ARCH_SA1100 && !ARCH_CLPS711X && !PARISC  config M32R_PCC  	bool "M32R PCMCIA I/F" @@ -241,6 +266,9 @@ config OMAP_CF  config PCCARD_NONSTATIC  	tristate +config PCCARD_IODYN +	bool +  endif	# PCCARD  endmenu diff --git a/drivers/pcmcia/au1000_generic.c b/drivers/pcmcia/au1000_generic.c index 87302c548c24..971a35281649 100644 --- a/drivers/pcmcia/au1000_generic.c +++ b/drivers/pcmcia/au1000_generic.c @@ -241,23 +241,6 @@ au1x00_pcmcia_get_status(struct pcmcia_socket *sock, unsigned int *status)  	return 0;  } -/* au1x00_pcmcia_get_socket() - * Implements the get_socket() operation for the in-kernel PCMCIA - * service (formerly SS_GetSocket in Card Services). Not a very - * exciting routine. - * - * Returns: 0 - */ -static int -au1x00_pcmcia_get_socket(struct pcmcia_socket *sock, socket_state_t *state) -{ -  struct au1000_pcmcia_socket *skt = to_au1000_socket(sock); - -  debug("for sock %u\n", skt->nr); -  *state = skt->cs_state; -  return 0; -} -  /* au1x00_pcmcia_set_socket()   * Implements the set_socket() operation for the in-kernel PCMCIA   * service (formerly SS_SetSocket in Card Services). We more or @@ -352,7 +335,6 @@ static struct pccard_operations au1x00_pcmcia_operations = {  	.init			= au1x00_pcmcia_sock_init,  	.suspend		= au1x00_pcmcia_suspend,  	.get_status		= au1x00_pcmcia_get_status, -	.get_socket		= au1x00_pcmcia_get_socket,  	.set_socket		= au1x00_pcmcia_set_socket,  	.set_io_map		= au1x00_pcmcia_set_io_map,  	.set_mem_map		= au1x00_pcmcia_set_mem_map, @@ -372,13 +354,12 @@ int au1x00_pcmcia_socket_probe(struct device *dev, struct pcmcia_low_level *ops,  	struct skt_dev_info *sinfo;  	int ret, i; -	sinfo = kmalloc(sizeof(struct skt_dev_info), GFP_KERNEL); +	sinfo = kzalloc(sizeof(struct skt_dev_info), GFP_KERNEL);  	if (!sinfo) {  		ret = -ENOMEM;  		goto out;  	} -	memset(sinfo, 0, sizeof(struct skt_dev_info));  	sinfo->nskt = nr;  	/* diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c index 2dc3e611a9a3..120fa8da6392 100644 --- a/drivers/pcmcia/cistpl.c +++ b/drivers/pcmcia/cistpl.c @@ -60,9 +60,9 @@ static const u_int exponent[] = {  /* Parameters that can be set with 'insmod' */ -#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0444) - -INT_MODULE_PARM(cis_width,	0);		/* 16-bit CIS? */ +/* 16-bit CIS? */ +static int cis_width; +module_param(cis_width, int, 0444);  void release_cis_mem(struct pcmcia_socket *s)  { @@ -463,7 +463,7 @@ static int follow_link(struct pcmcia_socket *s, tuple_t *tuple)  	/* Get indirect link from the MFC tuple */  	read_cis_cache(s, LINK_SPACE(tuple->Flags),  		       tuple->LinkOffset, 5, link); -	ofs = le32_to_cpu(*(u_int *)(link+1)); +	ofs = le32_to_cpu(*(__le32 *)(link+1));  	SPACE(tuple->Flags) = (link[0] == CISTPL_MFC_ATTR);  	/* Move to the next indirect link */  	tuple->LinkOffset += 5; @@ -671,8 +671,8 @@ static int parse_checksum(tuple_t *tuple, cistpl_checksum_t *csum)      if (tuple->TupleDataLen < 5)  	return CS_BAD_TUPLE;      p = (u_char *)tuple->TupleData; -    csum->addr = tuple->CISOffset+(short)le16_to_cpu(*(u_short *)p)-2; -    csum->len = le16_to_cpu(*(u_short *)(p + 2)); +    csum->addr = tuple->CISOffset+(short)le16_to_cpu(*(__le16 *)p)-2; +    csum->len = le16_to_cpu(*(__le16 *)(p + 2));      csum->sum = *(p+4);      return CS_SUCCESS;  } @@ -683,7 +683,7 @@ static int parse_longlink(tuple_t *tuple, cistpl_longlink_t *link)  {      if (tuple->TupleDataLen < 4)  	return CS_BAD_TUPLE; -    link->addr = le32_to_cpu(*(u_int *)tuple->TupleData); +    link->addr = le32_to_cpu(*(__le32 *)tuple->TupleData);      return CS_SUCCESS;  } @@ -702,7 +702,7 @@ static int parse_longlink_mfc(tuple_t *tuple,  	return CS_BAD_TUPLE;      for (i = 0; i < link->nfn; i++) {  	link->fn[i].space = *p; p++; -	link->fn[i].addr = le32_to_cpu(*(u_int *)p); p += 4; +	link->fn[i].addr = le32_to_cpu(*(__le32 *)p); p += 4;      }      return CS_SUCCESS;  } @@ -789,10 +789,10 @@ static int parse_jedec(tuple_t *tuple, cistpl_jedec_t *jedec)  static int parse_manfid(tuple_t *tuple, cistpl_manfid_t *m)  { -    u_short *p; +    __le16 *p;      if (tuple->TupleDataLen < 4)  	return CS_BAD_TUPLE; -    p = (u_short *)tuple->TupleData; +    p = (__le16 *)tuple->TupleData;      m->manf = le16_to_cpu(p[0]);      m->card = le16_to_cpu(p[1]);      return CS_SUCCESS; @@ -1093,7 +1093,7 @@ static int parse_cftable_entry(tuple_t *tuple,  	break;      case 0x20:  	entry->mem.nwin = 1; -	entry->mem.win[0].len = le16_to_cpu(*(u_short *)p) << 8; +	entry->mem.win[0].len = le16_to_cpu(*(__le16 *)p) << 8;  	entry->mem.win[0].card_addr = 0;  	entry->mem.win[0].host_addr = 0;  	p += 2; @@ -1101,9 +1101,9 @@ static int parse_cftable_entry(tuple_t *tuple,  	break;      case 0x40:  	entry->mem.nwin = 1; -	entry->mem.win[0].len = le16_to_cpu(*(u_short *)p) << 8; +	entry->mem.win[0].len = le16_to_cpu(*(__le16 *)p) << 8;  	entry->mem.win[0].card_addr = -	    le16_to_cpu(*(u_short *)(p+2)) << 8; +	    le16_to_cpu(*(__le16 *)(p+2)) << 8;  	entry->mem.win[0].host_addr = 0;  	p += 4;  	if (p > q) return CS_BAD_TUPLE; @@ -1140,7 +1140,7 @@ static int parse_bar(tuple_t *tuple, cistpl_bar_t *bar)      p = (u_char *)tuple->TupleData;      bar->attr = *p;      p += 2; -    bar->size = le32_to_cpu(*(u_int *)p); +    bar->size = le32_to_cpu(*(__le32 *)p);      return CS_SUCCESS;  } @@ -1153,7 +1153,7 @@ static int parse_config_cb(tuple_t *tuple, cistpl_config_t *config)  	return CS_BAD_TUPLE;      config->last_idx = *(++p);      p++; -    config->base = le32_to_cpu(*(u_int *)p); +    config->base = le32_to_cpu(*(__le32 *)p);      config->subtuples = tuple->TupleDataLen - 6;      return CS_SUCCESS;  } @@ -1269,7 +1269,7 @@ static int parse_vers_2(tuple_t *tuple, cistpl_vers_2_t *v2)      v2->vers = p[0];      v2->comply = p[1]; -    v2->dindex = le16_to_cpu(*(u_short *)(p+2)); +    v2->dindex = le16_to_cpu(*(__le16 *)(p+2));      v2->vspec8 = p[6];      v2->vspec9 = p[7];      v2->nhdr = p[8]; @@ -1310,8 +1310,8 @@ static int parse_format(tuple_t *tuple, cistpl_format_t *fmt)      fmt->type = p[0];      fmt->edc = p[1]; -    fmt->offset = le32_to_cpu(*(u_int *)(p+2)); -    fmt->length = le32_to_cpu(*(u_int *)(p+6)); +    fmt->offset = le32_to_cpu(*(__le32 *)(p+2)); +    fmt->length = le32_to_cpu(*(__le32 *)(p+6));      return CS_SUCCESS;  } diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c index 7cf09084ef61..613f2f1fbfdd 100644 --- a/drivers/pcmcia/cs.c +++ b/drivers/pcmcia/cs.c @@ -309,41 +309,6 @@ struct pcmcia_socket * pcmcia_get_socket_by_nr(unsigned int nr)  }  EXPORT_SYMBOL(pcmcia_get_socket_by_nr); - -/** - * socket_setup() and shutdown_socket() are called by the main event - * handler when card insertion and removal events are received. - * socket_setup() turns on socket power and resets the socket, in two stages. - * shutdown_socket() unconfigures a socket and turns off socket power. - */ -static void shutdown_socket(struct pcmcia_socket *s) -{ -	cs_dbg(s, 1, "shutdown_socket\n"); - -	/* Blank out the socket state */ -	s->socket = dead_socket; -	s->ops->init(s); -	s->ops->set_socket(s, &s->socket); -	s->irq.AssignedIRQ = s->irq.Config = 0; -	s->lock_count = 0; -	destroy_cis_cache(s); -#ifdef CONFIG_CARDBUS -	cb_free(s); -#endif -	s->functions = 0; -	kfree(s->config); -	s->config = NULL; - -	{ -		int status; -		s->ops->get_status(s, &status); -		if (status & SS_POWERON) { -			printk(KERN_ERR "PCMCIA: socket %p: *** DANGER *** unable to remove socket power\n", s); -		} -	} -} /* shutdown_socket */ - -  /**   * The central event handler.  Send_event() sends an event to the   * 16-bit subsystem, which then calls the relevant device drivers. @@ -383,17 +348,6 @@ static void socket_remove_drivers(struct pcmcia_socket *skt)  	send_event(skt, CS_EVENT_CARD_REMOVAL, CS_EVENT_PRI_HIGH);  } -static void socket_shutdown(struct pcmcia_socket *skt) -{ -	cs_dbg(skt, 4, "shutdown\n"); - -	socket_remove_drivers(skt); -	skt->state &= SOCKET_INUSE|SOCKET_PRESENT; -	msleep(shutdown_delay * 10); -	skt->state &= SOCKET_INUSE; -	shutdown_socket(skt); -} -  static int socket_reset(struct pcmcia_socket *skt)  {  	int status, i; @@ -424,6 +378,45 @@ static int socket_reset(struct pcmcia_socket *skt)  	return CS_GENERAL_FAILURE;  } +/** + * socket_setup() and socket_shutdown() are called by the main event handler + * when card insertion and removal events are received. + * socket_setup() turns on socket power and resets the socket, in two stages. + * socket_shutdown() unconfigures a socket and turns off socket power. + */ +static void socket_shutdown(struct pcmcia_socket *s) +{ +	int status; + +	cs_dbg(s, 4, "shutdown\n"); + +	socket_remove_drivers(s); +	s->state &= SOCKET_INUSE | SOCKET_PRESENT; +	msleep(shutdown_delay * 10); +	s->state &= SOCKET_INUSE; + +	/* Blank out the socket state */ +	s->socket = dead_socket; +	s->ops->init(s); +	s->ops->set_socket(s, &s->socket); +	s->irq.AssignedIRQ = s->irq.Config = 0; +	s->lock_count = 0; +	destroy_cis_cache(s); +#ifdef CONFIG_CARDBUS +	cb_free(s); +#endif +	s->functions = 0; +	kfree(s->config); +	s->config = NULL; + +	s->ops->get_status(s, &status); +	if (status & SS_POWERON) { +		printk(KERN_ERR "PCMCIA: socket %p: *** DANGER *** unable to remove socket power\n", s); +	} + +	cs_socket_put(s); +} +  static int socket_setup(struct pcmcia_socket *skt, int initial_delay)  {  	int status, i; @@ -529,7 +522,6 @@ static int socket_insert(struct pcmcia_socket *skt)  		send_event(skt, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW);  	} else {  		socket_shutdown(skt); -		cs_socket_put(skt);  	}  	return ret; @@ -593,7 +585,6 @@ static int socket_resume(struct pcmcia_socket *skt)  		}  	} else {  		socket_shutdown(skt); -		cs_socket_put(skt);  	}  	skt->state &= ~SOCKET_SUSPEND; @@ -605,7 +596,6 @@ static void socket_remove(struct pcmcia_socket *skt)  {  	printk(KERN_NOTICE "pccard: card ejected from slot %d\n", skt->sock);  	socket_shutdown(skt); -	cs_socket_put(skt);  }  /* @@ -780,8 +770,13 @@ int pccard_reset_card(struct pcmcia_socket *skt)  		ret = send_event(skt, CS_EVENT_RESET_REQUEST, CS_EVENT_PRI_LOW);  		if (ret == 0) {  			send_event(skt, CS_EVENT_RESET_PHYSICAL, CS_EVENT_PRI_LOW); -			if (socket_reset(skt) == CS_SUCCESS) +			if (skt->callback) +				skt->callback->suspend(skt); +			if (socket_reset(skt) == CS_SUCCESS) {  				send_event(skt, CS_EVENT_CARD_RESET, CS_EVENT_PRI_LOW); +				if (skt->callback) +					skt->callback->resume(skt); +			}  		}  		ret = CS_SUCCESS; @@ -812,6 +807,11 @@ int pcmcia_suspend_card(struct pcmcia_socket *skt)  			ret = CS_UNSUPPORTED_FUNCTION;  			break;  		} +		if (skt->callback) { +			ret = skt->callback->suspend(skt); +			if (ret) +				break; +		}  		ret = socket_suspend(skt);  	} while (0);  	up(&skt->skt_sem); @@ -838,6 +838,8 @@ int pcmcia_resume_card(struct pcmcia_socket *skt)  			break;  		}  		ret = socket_resume(skt); +		if (!ret && skt->callback) +			skt->callback->resume(skt);  	} while (0);  	up(&skt->skt_sem); diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h index 55867bc7f199..7b37eba35bf1 100644 --- a/drivers/pcmcia/cs_internal.h +++ b/drivers/pcmcia/cs_internal.h @@ -117,7 +117,7 @@ int verify_cis_cache(struct pcmcia_socket *s);  int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function, cisdata_t code, void *parse);  /* In rsrc_mgr */ -void pcmcia_validate_mem(struct pcmcia_socket *s); +int pcmcia_validate_mem(struct pcmcia_socket *s);  struct resource *pcmcia_find_io_region(unsigned long base, int num, unsigned long align,  		   struct pcmcia_socket *s);  int pcmcia_adjust_io_region(struct resource *res, unsigned long r_start, @@ -143,6 +143,8 @@ struct pcmcia_callback{  	struct module	*owner;  	int		(*event) (struct pcmcia_socket *s, event_t event, int priority);  	void		(*requery) (struct pcmcia_socket *s); +	int		(*suspend) (struct pcmcia_socket *s); +	int		(*resume) (struct pcmcia_socket *s);  };  int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c); diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 6fb76399547e..0252582b91cd 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -57,8 +57,6 @@ module_param_named(pc_debug, ds_pc_debug, int, 0644);  spinlock_t pcmcia_dev_list_lock; -static int unbind_request(struct pcmcia_socket *s); -  /*====================================================================*/  /* code which was in cs.c before */ @@ -205,7 +203,7 @@ static void pcmcia_check_driver(struct pcmcia_driver *p_drv)  	unsigned int i;  	u32 hash; -	if (!p_drv->attach || !p_drv->event || !p_drv->detach) +	if (!p_drv->probe || !p_drv->remove)  		printk(KERN_DEBUG "pcmcia: %s lacks a requisite callback "  		       "function\n", p_drv->drv.name); @@ -266,12 +264,10 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename)  		if (fw->size >= CISTPL_MAX_CIS_SIZE)  			goto release; -		cis = kmalloc(sizeof(cisdump_t), GFP_KERNEL); +		cis = kzalloc(sizeof(cisdump_t), GFP_KERNEL);  		if (!cis)  			goto release; -		memset(cis, 0, sizeof(cisdump_t)); -  		cis->Length = fw->size + 1;  		memcpy(cis->Data, fw->data, fw->size); @@ -363,6 +359,7 @@ static int pcmcia_device_probe(struct device * dev)  {  	struct pcmcia_device *p_dev;  	struct pcmcia_driver *p_drv; +	struct pcmcia_socket *s;  	int ret = 0;  	dev = get_device(dev); @@ -371,25 +368,38 @@ static int pcmcia_device_probe(struct device * dev)  	p_dev = to_pcmcia_dev(dev);  	p_drv = to_pcmcia_drv(dev->driver); +	s = p_dev->socket; -	if (!try_module_get(p_drv->owner)) { +	if ((!p_drv->probe) || (!try_module_get(p_drv->owner))) {  		ret = -EINVAL;  		goto put_dev;  	} -	if (p_drv->attach) { -		p_dev->instance = p_drv->attach(); -		if ((!p_dev->instance) || (p_dev->state & CLIENT_UNBOUND)) { -			printk(KERN_NOTICE "ds: unable to create instance " -			       "of '%s'!\n", p_drv->drv.name); -			ret = -EINVAL; +	p_dev->state &= ~CLIENT_UNBOUND; + +	/* set up the device configuration, if it hasn't been done before */ +	if (!s->functions) { +		cistpl_longlink_mfc_t mfc; +		if (pccard_read_tuple(s, p_dev->func, CISTPL_LONGLINK_MFC, +				      &mfc) == CS_SUCCESS) +			s->functions = mfc.nfn; +		else +			s->functions = 1; +		s->config = kzalloc(sizeof(config_t) * s->functions, +				    GFP_KERNEL); +		if (!s->config) { +			ret = -ENOMEM; +			goto put_module;  		}  	} +	ret = p_drv->probe(p_dev); + + put_module:  	if (ret)  		module_put(p_drv->owner);   put_dev: -	if ((ret) || !(p_drv->attach)) +	if (ret)  		put_device(dev);  	return (ret);  } @@ -399,24 +409,66 @@ static int pcmcia_device_remove(struct device * dev)  {  	struct pcmcia_device *p_dev;  	struct pcmcia_driver *p_drv; +	int i;  	/* detach the "instance" */  	p_dev = to_pcmcia_dev(dev);  	p_drv = to_pcmcia_drv(dev->driver); +	if (!p_drv) +		return 0; -	if (p_drv) { -		if ((p_drv->detach) && (p_dev->instance)) { -			p_drv->detach(p_dev->instance); -			/* from pcmcia_probe_device */ -			put_device(&p_dev->dev); -		} -		module_put(p_drv->owner); -	} +	if (p_drv->remove) +	       	p_drv->remove(p_dev); + +	/* check for proper unloading */ +	if (p_dev->state & (CLIENT_IRQ_REQ|CLIENT_IO_REQ|CLIENT_CONFIG_LOCKED)) +		printk(KERN_INFO "pcmcia: driver %s did not release config properly\n", +		       p_drv->drv.name); + +	for (i = 0; i < MAX_WIN; i++) +		if (p_dev->state & CLIENT_WIN_REQ(i)) +			printk(KERN_INFO "pcmcia: driver %s did not release windows properly\n", +			       p_drv->drv.name); + +	/* references from pcmcia_probe_device */ +	p_dev->state = CLIENT_UNBOUND; +	pcmcia_put_dev(p_dev); +	module_put(p_drv->owner);  	return 0;  } +/* + * Removes a PCMCIA card from the device tree and socket list. + */ +static void pcmcia_card_remove(struct pcmcia_socket *s) +{ +	struct pcmcia_device	*p_dev; +	unsigned long		flags; + +	ds_dbg(2, "unbind_request(%d)\n", s->sock); + +	s->device_count = 0; + +	for (;;) { +		/* unregister all pcmcia_devices registered with this socket*/ +		spin_lock_irqsave(&pcmcia_dev_list_lock, flags); +		if (list_empty(&s->devices_list)) { +			spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); + 			return; +		} +		p_dev = list_entry((&s->devices_list)->next, struct pcmcia_device, socket_device_list); +		list_del(&p_dev->socket_device_list); +		p_dev->state |= CLIENT_STALE; +		spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); + +		device_unregister(&p_dev->dev); +	} + +	return; +} /* unbind_request */ +  /*   * pcmcia_device_query -- determine information about a pcmcia device @@ -517,10 +569,9 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f  	if (s->device_count == 2)  		goto err_put; -	p_dev = kmalloc(sizeof(struct pcmcia_device), GFP_KERNEL); +	p_dev = kzalloc(sizeof(struct pcmcia_device), GFP_KERNEL);  	if (!p_dev)  		goto err_put; -	memset(p_dev, 0, sizeof(struct pcmcia_device));  	p_dev->socket = s;  	p_dev->device_no = (s->device_count++); @@ -583,7 +634,9 @@ static int pcmcia_card_add(struct pcmcia_socket *s)  	if (!(s->resource_setup_done))  		return -EAGAIN; /* try again, but later... */ -	pcmcia_validate_mem(s); +	if (pcmcia_validate_mem(s)) +		return -EAGAIN; /* try again, but later... */ +  	ret = pccard_validate_cis(s, BIND_FN_ALL, &cisinfo);  	if (ret || !cisinfo.Chains) {  		ds_dbg(0, "invalid CIS or invalid resources\n"); @@ -918,55 +971,84 @@ static struct device_attribute pcmcia_dev_attrs[] = {  	__ATTR_NULL,  }; +/* PM support, also needed for reset */ -/*====================================================================== +static int pcmcia_dev_suspend(struct device * dev, pm_message_t state) +{ +	struct pcmcia_device *p_dev = to_pcmcia_dev(dev); +	struct pcmcia_driver *p_drv = NULL; -    The card status event handler. -     -======================================================================*/ +	if (dev->driver) +		p_drv = to_pcmcia_drv(dev->driver); -struct send_event_data { -	struct pcmcia_socket *skt; -	event_t event; -	int priority; -}; +	if (p_drv && p_drv->suspend) +		return p_drv->suspend(p_dev); + +	return 0; +} -static int send_event_callback(struct device *dev, void * _data) + +static int pcmcia_dev_resume(struct device * dev)  {  	struct pcmcia_device *p_dev = to_pcmcia_dev(dev); -	struct pcmcia_driver *p_drv; -	struct send_event_data *data = _data; +        struct pcmcia_driver *p_drv = NULL; -	/* we get called for all sockets, but may only pass the event -	 * for drivers _on the affected socket_ */ -	if (p_dev->socket != data->skt) -		return 0; +	if (dev->driver) +		p_drv = to_pcmcia_drv(dev->driver); -	p_drv = to_pcmcia_drv(p_dev->dev.driver); -	if (!p_drv) +	if (p_drv && p_drv->resume) +		return p_drv->resume(p_dev); + +	return 0; +} + + +static int pcmcia_bus_suspend_callback(struct device *dev, void * _data) +{ +	struct pcmcia_socket *skt = _data; +	struct pcmcia_device *p_dev = to_pcmcia_dev(dev); + +	if (p_dev->socket != skt)  		return 0; -	if (p_dev->state & (CLIENT_UNBOUND|CLIENT_STALE)) +	return dpm_runtime_suspend(dev, PMSG_SUSPEND); +} + +static int pcmcia_bus_resume_callback(struct device *dev, void * _data) +{ +	struct pcmcia_socket *skt = _data; +	struct pcmcia_device *p_dev = to_pcmcia_dev(dev); + +	if (p_dev->socket != skt)  		return 0; -	if (p_drv->event) -		return p_drv->event(data->event, data->priority, -				    &p_dev->event_callback_args); +	dpm_runtime_resume(dev);  	return 0;  } -static int send_event(struct pcmcia_socket *s, event_t event, int priority) +static int pcmcia_bus_resume(struct pcmcia_socket *skt)  { -	struct send_event_data private; +	bus_for_each_dev(&pcmcia_bus_type, NULL, skt, pcmcia_bus_resume_callback); +	return 0; +} + +static int pcmcia_bus_suspend(struct pcmcia_socket *skt) +{ +	if (bus_for_each_dev(&pcmcia_bus_type, NULL, skt, +			     pcmcia_bus_suspend_callback)) { +		pcmcia_bus_resume(skt); +		return -EIO; +	} +	return 0; +} -	private.skt = s; -	private.event = event; -	private.priority = priority; -	return bus_for_each_dev(&pcmcia_bus_type, NULL, &private, send_event_callback); -} /* send_event */ +/*====================================================================== +    The card status event handler. +     +======================================================================*/  /* Normally, the event is passed to individual drivers after   * informing userspace. Only for CS_EVENT_CARD_REMOVAL this @@ -976,20 +1058,17 @@ static int send_event(struct pcmcia_socket *s, event_t event, int priority)  static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)  {  	struct pcmcia_socket *s = pcmcia_get_socket(skt); -	int ret = 0;  	ds_dbg(1, "ds_event(0x%06x, %d, 0x%p)\n",  	       event, priority, skt); -     -	switch (event) { +	switch (event) {  	case CS_EVENT_CARD_REMOVAL:  		s->pcmcia_state.present = 0; -	    	send_event(skt, event, priority); -		unbind_request(skt); +		pcmcia_card_remove(skt);  		handle_event(skt, event);  		break; -	 +  	case CS_EVENT_CARD_INSERTION:  		s->pcmcia_state.present = 1;  		pcmcia_card_add(skt); @@ -997,12 +1076,14 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)  		break;  	case CS_EVENT_EJECTION_REQUEST: -		ret = send_event(skt, event, priority);  		break; +	case CS_EVENT_PM_SUSPEND: +	case CS_EVENT_PM_RESUME: +	case CS_EVENT_RESET_PHYSICAL: +	case CS_EVENT_CARD_RESET:  	default:  		handle_event(skt, event); -		send_event(skt, event, priority);  		break;      } @@ -1012,152 +1093,12 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)  } /* ds_event */ - -int pcmcia_register_client(struct pcmcia_device **handle, client_reg_t *req) -{ -	struct pcmcia_socket *s = NULL; -	struct pcmcia_device *p_dev = NULL; -	struct pcmcia_driver *p_drv = NULL; - -	/* Look for unbound client with matching dev_info */ -	down_read(&pcmcia_socket_list_rwsem); -	list_for_each_entry(s, &pcmcia_socket_list, socket_list) { -		unsigned long flags; - -		if (s->state & SOCKET_CARDBUS) -			continue; - -		s = pcmcia_get_socket(s); -		if (!s) -			continue; -		spin_lock_irqsave(&pcmcia_dev_list_lock, flags); -		list_for_each_entry(p_dev, &s->devices_list, socket_device_list) { -			p_dev = pcmcia_get_dev(p_dev); -			if (!p_dev) -				continue; -			if (!(p_dev->state & CLIENT_UNBOUND) || -			    (!p_dev->dev.driver)) { -				pcmcia_put_dev(p_dev); -				continue; -			} -			p_drv = to_pcmcia_drv(p_dev->dev.driver); -			if (!strncmp(p_drv->drv.name, (char *)req->dev_info, DEV_NAME_LEN)) { -				spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); -				goto found; -			} -			pcmcia_put_dev(p_dev); -		} -		spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); -		pcmcia_put_socket(s); -	} - found: -	up_read(&pcmcia_socket_list_rwsem); -	if (!p_dev) -		return -ENODEV; - -	pcmcia_put_socket(s); /* safe, as we already hold a reference from bind_device */ - -	*handle = p_dev; -	p_dev->state &= ~CLIENT_UNBOUND; -	p_dev->event_callback_args = req->event_callback_args; -	p_dev->event_callback_args.client_handle = p_dev; - - -	if (!s->functions) { -		cistpl_longlink_mfc_t mfc; -		if (pccard_read_tuple(s, p_dev->func, CISTPL_LONGLINK_MFC, &mfc) -		    == CS_SUCCESS) -			s->functions = mfc.nfn; -		else -			s->functions = 1; -		s->config = kmalloc(sizeof(config_t) * s->functions, -				    GFP_KERNEL); -		if (!s->config) -			goto out_no_resource; -		memset(s->config, 0, sizeof(config_t) * s->functions); -	} - -	ds_dbg(1, "register_client(): client 0x%p, dev %s\n", -	       p_dev, p_dev->dev.bus_id); - -	if ((s->state & (SOCKET_PRESENT|SOCKET_CARDBUS)) == SOCKET_PRESENT) { -		if (p_drv->event) -			p_drv->event(CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW, -				     &p_dev->event_callback_args); - -	} - -	return CS_SUCCESS; - - out_no_resource: -	pcmcia_put_dev(p_dev); -	return CS_OUT_OF_RESOURCE; -} /* register_client */ -EXPORT_SYMBOL(pcmcia_register_client); - - -/* unbind _all_ devices attached to a given pcmcia_bus_socket. The - * drivers have been called with EVENT_CARD_REMOVAL before. - */ -static int unbind_request(struct pcmcia_socket *s) -{ -	struct pcmcia_device	*p_dev; -	unsigned long		flags; - -	ds_dbg(2, "unbind_request(%d)\n", s->sock); - -	s->device_count = 0; - -	for (;;) { -		/* unregister all pcmcia_devices registered with this socket*/ -		spin_lock_irqsave(&pcmcia_dev_list_lock, flags); -		if (list_empty(&s->devices_list)) { -			spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); - 			return 0; -		} -		p_dev = list_entry((&s->devices_list)->next, struct pcmcia_device, socket_device_list); -		list_del(&p_dev->socket_device_list); -		p_dev->state |= CLIENT_STALE; -		spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); - -		device_unregister(&p_dev->dev); -	} - -	return 0; -} /* unbind_request */ - -int pcmcia_deregister_client(struct pcmcia_device *p_dev) -{ -	struct pcmcia_socket *s; -	int i; - -	s = p_dev->socket; -	ds_dbg(1, "deregister_client(%p)\n", p_dev); - -	if (p_dev->state & (CLIENT_IRQ_REQ|CLIENT_IO_REQ|CLIENT_CONFIG_LOCKED)) -		goto warn_out; -	for (i = 0; i < MAX_WIN; i++) -		if (p_dev->state & CLIENT_WIN_REQ(i)) -			goto warn_out; - -	if (p_dev->state & CLIENT_STALE) { -		p_dev->state &= ~CLIENT_STALE; -		pcmcia_put_dev(p_dev); -	} else { -		p_dev->state = CLIENT_UNBOUND; -	} - -	return CS_SUCCESS; - warn_out: -	printk(KERN_WARNING "ds: deregister_client was called too early.\n"); -	return CS_IN_USE; -} /* deregister_client */ -EXPORT_SYMBOL(pcmcia_deregister_client); -  static struct pcmcia_callback pcmcia_bus_callback = {  	.owner = THIS_MODULE,  	.event = ds_event,  	.requery = pcmcia_bus_rescan, +	.suspend = pcmcia_bus_suspend, +	.resume = pcmcia_bus_resume,  };  static int __devinit pcmcia_bus_add_socket(struct class_device *class_dev, @@ -1226,6 +1167,8 @@ struct bus_type pcmcia_bus_type = {  	.uevent = pcmcia_bus_uevent,  	.match = pcmcia_bus_match,  	.dev_attrs = pcmcia_dev_attrs, +	.suspend = pcmcia_dev_suspend, +	.resume = pcmcia_dev_resume,  }; diff --git a/drivers/pcmcia/hd64465_ss.c b/drivers/pcmcia/hd64465_ss.c index 561706ba4499..b39435bbfaeb 100644 --- a/drivers/pcmcia/hd64465_ss.c +++ b/drivers/pcmcia/hd64465_ss.c @@ -417,18 +417,6 @@ static int hs_get_status(struct pcmcia_socket *s, u_int *value)  /*============================================================*/ -static int hs_get_socket(struct pcmcia_socket *s, socket_state_t *state) -{ -    	hs_socket_t *sp = container_of(s, struct hs_socket_t, socket); - -    	DPRINTK("hs_get_socket(%d)\n", sock); -	 -	*state = sp->state; -	return 0; -} - -/*============================================================*/ -  static int hs_set_socket(struct pcmcia_socket *s, socket_state_t *state)  {      	hs_socket_t *sp = container_of(s, struct hs_socket_t, socket); @@ -749,7 +737,6 @@ static irqreturn_t hs_interrupt(int irq, void *dev, struct pt_regs *regs)  static struct pccard_operations hs_operations = {  	.init			= hs_init,  	.get_status		= hs_get_status, -	.get_socket		= hs_get_socket,  	.set_socket		= hs_set_socket,  	.set_io_map		= hs_set_io_map,  	.set_mem_map		= hs_set_mem_map, diff --git a/drivers/pcmcia/i82092.c b/drivers/pcmcia/i82092.c index f3fdc748659d..7979c85df3dc 100644 --- a/drivers/pcmcia/i82092.c +++ b/drivers/pcmcia/i82092.c @@ -66,7 +66,6 @@ static struct pci_driver i82092aa_pci_drv = {  static struct pccard_operations i82092aa_operations = {  	.init 		 	= i82092aa_init,  	.get_status		= i82092aa_get_status, -	.get_socket		= i82092aa_get_socket,  	.set_socket		= i82092aa_set_socket,  	.set_io_map		= i82092aa_set_io_map,  	.set_mem_map		= i82092aa_set_mem_map, @@ -482,78 +481,6 @@ static int i82092aa_get_status(struct pcmcia_socket *socket, u_int *value)  } -static int i82092aa_get_socket(struct pcmcia_socket *socket, socket_state_t *state)  -{ -	unsigned int sock = container_of(socket, struct socket_info, socket)->number; -	unsigned char reg,vcc,vpp; -	 -	enter("i82092aa_get_socket"); -	state->flags    = 0; -	state->Vcc      = 0; -	state->Vpp      = 0; -	state->io_irq   = 0; -	state->csc_mask = 0; - -	/* First the power status of the socket */ -	reg = indirect_read(sock,I365_POWER); /* PCTRL - Power Control Register */ - -	if (reg & I365_PWR_AUTO) -		state->flags |= SS_PWR_AUTO;  /* Automatic Power Switch */ -		 -	if (reg & I365_PWR_OUT) -		state->flags |= SS_OUTPUT_ENA; /* Output signals are enabled */ -		 -	vcc = reg & I365_VCC_MASK;    vpp = reg & I365_VPP1_MASK; -	 -	if (reg & I365_VCC_5V) { /* Can still be 3.3V, in this case the Vcc value will be overwritten later */ -		state->Vcc = 50; -		 -		if (vpp == I365_VPP1_5V) -			state->Vpp = 50; -		if (vpp == I365_VPP1_12V) -			state->Vpp = 120; -			 -	} -	 -	if ((reg & I365_VCC_3V)==I365_VCC_3V) -		state->Vcc = 33; -	 -	 -	/* Now the IO card, RESET flags and IO interrupt */ -	 -	reg = indirect_read(sock, I365_INTCTL); /* IGENC, Interrupt and General Control */ -	 -	if ((reg & I365_PC_RESET)==0) -		state->flags |= SS_RESET; -	if (reg & I365_PC_IOCARD)  -		state->flags |= SS_IOCARD; /* This is an IO card */ -	 -	/* Set the IRQ number */ -	if (sockets[sock].dev!=NULL) -		state->io_irq = sockets[sock].dev->irq; -	 -	/* Card status change */ -	reg = indirect_read(sock, I365_CSCINT); /* CSCICR, Card Status Change Interrupt Configuration */ -	 -	if (reg & I365_CSC_DETECT)  -		state->csc_mask |= SS_DETECT; /* Card detect is enabled */ -	 -	if (state->flags & SS_IOCARD) {/* IO Cards behave different */ -		if (reg & I365_CSC_STSCHG) -			state->csc_mask |= SS_STSCHG; -	} else { -		if (reg & I365_CSC_BVD1)  -			state->csc_mask |= SS_BATDEAD; -		if (reg & I365_CSC_BVD2)  -			state->csc_mask |= SS_BATWARN; -		if (reg & I365_CSC_READY)  -			state->csc_mask |= SS_READY; -	} -		 -	leave("i82092aa_get_socket"); -	return 0; -} -  static int i82092aa_set_socket(struct pcmcia_socket *socket, socket_state_t *state)   {  	unsigned int sock = container_of(socket, struct socket_info, socket)->number; diff --git a/drivers/pcmcia/i82092aa.h b/drivers/pcmcia/i82092aa.h index b98cac7bda9f..9c14599d0673 100644 --- a/drivers/pcmcia/i82092aa.h +++ b/drivers/pcmcia/i82092aa.h @@ -29,7 +29,6 @@ static irqreturn_t i82092aa_interrupt(int irq, void *dev, struct pt_regs *regs);  static int i82092aa_get_status(struct pcmcia_socket *socket, u_int *value); -static int i82092aa_get_socket(struct pcmcia_socket *socket, socket_state_t *state);  static int i82092aa_set_socket(struct pcmcia_socket *socket, socket_state_t *state);  static int i82092aa_set_io_map(struct pcmcia_socket *socket, struct pccard_io_map *io);  static int i82092aa_set_mem_map(struct pcmcia_socket *socket, struct pccard_mem_map *mem); diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c index 4d56bc9926d6..35a92d1e4945 100644 --- a/drivers/pcmcia/i82365.c +++ b/drivers/pcmcia/i82365.c @@ -940,78 +940,6 @@ static int i365_get_status(u_short sock, u_int *value)  /*====================================================================*/ -static int i365_get_socket(u_short sock, socket_state_t *state) -{ -    struct i82365_socket *t = &socket[sock]; -    u_char reg, vcc, vpp; -     -    reg = i365_get(sock, I365_POWER); -    state->flags = (reg & I365_PWR_AUTO) ? SS_PWR_AUTO : 0; -    state->flags |= (reg & I365_PWR_OUT) ? SS_OUTPUT_ENA : 0; -    vcc = reg & I365_VCC_MASK; vpp = reg & I365_VPP1_MASK; -    state->Vcc = state->Vpp = 0; -    if (t->flags & IS_CIRRUS) { -	if (i365_get(sock, PD67_MISC_CTL_1) & PD67_MC1_VCC_3V) { -	    if (reg & I365_VCC_5V) state->Vcc = 33; -	    if (vpp == I365_VPP1_5V) state->Vpp = 33; -	} else { -	    if (reg & I365_VCC_5V) state->Vcc = 50; -	    if (vpp == I365_VPP1_5V) state->Vpp = 50; -	} -	if (vpp == I365_VPP1_12V) state->Vpp = 120; -    } else if (t->flags & IS_VG_PWR) { -	if (i365_get(sock, VG469_VSELECT) & VG469_VSEL_VCC) { -	    if (reg & I365_VCC_5V) state->Vcc = 33; -	    if (vpp == I365_VPP1_5V) state->Vpp = 33; -	} else { -	    if (reg & I365_VCC_5V) state->Vcc = 50; -	    if (vpp == I365_VPP1_5V) state->Vpp = 50; -	} -	if (vpp == I365_VPP1_12V) state->Vpp = 120; -    } else if (t->flags & IS_DF_PWR) { -	if (vcc == I365_VCC_3V) state->Vcc = 33; -	if (vcc == I365_VCC_5V) state->Vcc = 50; -	if (vpp == I365_VPP1_5V) state->Vpp = 50; -	if (vpp == I365_VPP1_12V) state->Vpp = 120; -    } else { -	if (reg & I365_VCC_5V) { -	    state->Vcc = 50; -	    if (vpp == I365_VPP1_5V) state->Vpp = 50; -	    if (vpp == I365_VPP1_12V) state->Vpp = 120; -	} -    } - -    /* IO card, RESET flags, IO interrupt */ -    reg = i365_get(sock, I365_INTCTL); -    state->flags |= (reg & I365_PC_RESET) ? 0 : SS_RESET; -    if (reg & I365_PC_IOCARD) state->flags |= SS_IOCARD; -    state->io_irq = reg & I365_IRQ_MASK; -     -    /* speaker control */ -    if (t->flags & IS_CIRRUS) { -	if (i365_get(sock, PD67_MISC_CTL_1) & PD67_MC1_SPKR_ENA) -	    state->flags |= SS_SPKR_ENA; -    } -     -    /* Card status change mask */ -    reg = i365_get(sock, I365_CSCINT); -    state->csc_mask = (reg & I365_CSC_DETECT) ? SS_DETECT : 0; -    if (state->flags & SS_IOCARD) -	state->csc_mask |= (reg & I365_CSC_STSCHG) ? SS_STSCHG : 0; -    else { -	state->csc_mask |= (reg & I365_CSC_BVD1) ? SS_BATDEAD : 0; -	state->csc_mask |= (reg & I365_CSC_BVD2) ? SS_BATWARN : 0; -	state->csc_mask |= (reg & I365_CSC_READY) ? SS_READY : 0; -    } -     -    debug(1, "GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, " -	  "io_irq %d, csc_mask %#2.2x\n", sock, state->flags, -	  state->Vcc, state->Vpp, state->io_irq, state->csc_mask); -    return 0; -} /* i365_get_socket */ - -/*====================================================================*/ -  static int i365_set_socket(u_short sock, socket_state_t *state)  {      struct i82365_socket *t = &socket[sock]; @@ -1265,16 +1193,6 @@ static int pcic_get_status(struct pcmcia_socket *s, u_int *value)  	LOCKED(i365_get_status(sock, value));  } -static int pcic_get_socket(struct pcmcia_socket *s, socket_state_t *state) -{ -	unsigned int sock = container_of(s, struct i82365_socket, socket)->number; - -	if (socket[sock].flags & IS_ALIVE) -		return -EINVAL; - -	LOCKED(i365_get_socket(sock, state)); -} -  static int pcic_set_socket(struct pcmcia_socket *s, socket_state_t *state)  {  	unsigned int sock = container_of(s, struct i82365_socket, socket)->number; @@ -1324,7 +1242,6 @@ static int pcic_init(struct pcmcia_socket *s)  static struct pccard_operations pcic_operations = {  	.init			= pcic_init,  	.get_status		= pcic_get_status, -	.get_socket		= pcic_get_socket,  	.set_socket		= pcic_set_socket,  	.set_io_map		= pcic_set_io_map,  	.set_mem_map		= pcic_set_mem_map, diff --git a/drivers/pcmcia/m32r_cfc.c b/drivers/pcmcia/m32r_cfc.c index 078579ae6359..071cf485e1a3 100644 --- a/drivers/pcmcia/m32r_cfc.c +++ b/drivers/pcmcia/m32r_cfc.c @@ -480,25 +480,6 @@ static int _pcc_get_status(u_short sock, u_int *value)  /*====================================================================*/ -static int _pcc_get_socket(u_short sock, socket_state_t *state) -{ -//	pcc_socket_t *t = &socket[sock]; - -	state->flags = 0; -	state->csc_mask = SS_DETECT; -	state->csc_mask |= SS_READY; -	state->io_irq = 0; -	state->Vcc = 33;	/* 3.3V fixed */ -	state->Vpp = 33; - -	debug(3, "m32r_cfc: GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, " -		  "io_irq %d, csc_mask %#2.2x\n", sock, state->flags, -		  state->Vcc, state->Vpp, state->io_irq, state->csc_mask); -	return 0; -} /* _get_socket */ - -/*====================================================================*/ -  static int _pcc_set_socket(u_short sock, socket_state_t *state)  {  	debug(3, "m32r_cfc: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, " @@ -667,18 +648,6 @@ static int pcc_get_status(struct pcmcia_socket *s, u_int *value)  	LOCKED(_pcc_get_status(sock, value));  } -static int pcc_get_socket(struct pcmcia_socket *s, socket_state_t *state) -{ -	unsigned int sock = container_of(s, struct pcc_socket, socket)->number; - -	if (socket[sock].flags & IS_ALIVE) { -		debug(3, "m32r_cfc: pcc_get_socket: sock(%d) -EINVAL\n", sock); -		return -EINVAL; -	} -	debug(3, "m32r_cfc: pcc_get_socket: sock(%d)\n", sock); -	LOCKED(_pcc_get_socket(sock, state)); -} -  static int pcc_set_socket(struct pcmcia_socket *s, socket_state_t *state)  {  	unsigned int sock = container_of(s, struct pcc_socket, socket)->number; @@ -724,7 +693,6 @@ static int pcc_init(struct pcmcia_socket *s)  static struct pccard_operations pcc_operations = {  	.init			= pcc_init,  	.get_status		= pcc_get_status, -	.get_socket		= pcc_get_socket,  	.set_socket		= pcc_set_socket,  	.set_io_map		= pcc_set_io_map,  	.set_mem_map		= pcc_set_mem_map, diff --git a/drivers/pcmcia/m32r_pcc.c b/drivers/pcmcia/m32r_pcc.c index 356a6fb416a1..70d5f0748d55 100644 --- a/drivers/pcmcia/m32r_pcc.c +++ b/drivers/pcmcia/m32r_pcc.c @@ -429,16 +429,6 @@ static int _pcc_get_status(u_short sock, u_int *value)  /*====================================================================*/ -static int _pcc_get_socket(u_short sock, socket_state_t *state) -{ -	debug(3, "m32r-pcc: GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, " -		  "io_irq %d, csc_mask %#2.2x\n", sock, state->flags, -		  state->Vcc, state->Vpp, state->io_irq, state->csc_mask); -	return 0; -} /* _get_socket */ - -/*====================================================================*/ -  static int _pcc_set_socket(u_short sock, socket_state_t *state)  {  	u_long reg = 0; @@ -641,15 +631,6 @@ static int pcc_get_status(struct pcmcia_socket *s, u_int *value)  	LOCKED(_pcc_get_status(sock, value));  } -static int pcc_get_socket(struct pcmcia_socket *s, socket_state_t *state) -{ -	unsigned int sock = container_of(s, struct pcc_socket, socket)->number; - -	if (socket[sock].flags & IS_ALIVE) -		return -EINVAL; -	LOCKED(_pcc_get_socket(sock, state)); -} -  static int pcc_set_socket(struct pcmcia_socket *s, socket_state_t *state)  {  	unsigned int sock = container_of(s, struct pcc_socket, socket)->number; @@ -687,7 +668,6 @@ static int pcc_init(struct pcmcia_socket *s)  static struct pccard_operations pcc_operations = {  	.init			= pcc_init,  	.get_status		= pcc_get_status, -	.get_socket		= pcc_get_socket,  	.set_socket		= pcc_set_socket,  	.set_io_map		= pcc_set_io_map,  	.set_mem_map		= pcc_set_mem_map, diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c index 6d9f71cfcb34..0e07d9535116 100644 --- a/drivers/pcmcia/m8xx_pcmcia.c +++ b/drivers/pcmcia/m8xx_pcmcia.c @@ -9,6 +9,9 @@   *     <oliver.kurth@cyclades.de>   * Further fixes, v2.6 kernel port   *     <marcelo.tosatti@cyclades.com> + *  + * Some fixes, additions (C) 2005 Montavista Software, Inc.  + *     <vbordug@ru.mvista.com>   *   * "The ExCA standard specifies that socket controllers should provide   * two IO and five memory windows per socket, which can be independently @@ -97,6 +100,11 @@ MODULE_LICENSE("Dual MPL/GPL");  #endif  #endif +#if defined(CONFIG_MPC885ADS) +#define CONFIG_PCMCIA_SLOT_A +#define PCMCIA_GLITCHY_CD +#endif +  /* Cyclades ACS uses both slots */  #ifdef CONFIG_PRxK  #define CONFIG_PCMCIA_SLOT_A @@ -374,10 +382,10 @@ static int voltage_set(int slot, int vcc, int vpp)  	}  	/* first, turn off all power */ -	out_be32(&((u32 *)BCSR1), in_be32(&((u32 *)BCSR1)) & ~(BCSR1_PCCVCC_MASK | BCSR1_PCCVPP_MASK)); +	out_be32((u32 *)BCSR1, in_be32((u32 *)BCSR1) & ~(BCSR1_PCCVCC_MASK | BCSR1_PCCVPP_MASK));  	/* enable new powersettings */ -	out_be32(&((u32 *)BCSR1), in_be32(&((u32 *)BCSR1)) | reg); +	out_be32((u32 *)BCSR1, in_be32((u32 *)BCSR1) | reg);  	return 0;  } @@ -386,12 +394,89 @@ static int voltage_set(int slot, int vcc, int vpp)  static void hardware_enable(int slot)  { -	out_be32(&((u32 *)BCSR1), in_be32(&((u32 *)BCSR1)) & ~BCSR1_PCCEN); +	out_be32((u32 *)BCSR1, in_be32((u32 *)BCSR1) & ~BCSR1_PCCEN);  }  static void hardware_disable(int slot)  { -	out_be32(&((u32 *)BCSR1), in_be32(&((u32 *)BCSR1)) |  BCSR1_PCCEN); +	out_be32((u32 *)BCSR1, in_be32((u32 *)BCSR1) |  BCSR1_PCCEN); +} + +#endif + +/* MPC885ADS Boards */ + +#if defined(CONFIG_MPC885ADS) + +#define PCMCIA_BOARD_MSG "MPC885ADS" + +static int voltage_set(int slot, int vcc, int vpp) +{ +	u32 reg = 0; +	unsigned *bcsr_io; + +	bcsr_io = ioremap(BCSR1, sizeof(unsigned long)); + +	switch(vcc) { +		case 0: +			break; +		case 33: +			reg |= BCSR1_PCCVCC0; +			break; +		case 50: +			reg |= BCSR1_PCCVCC1; +			break; +		default: +			return 1; +	} + +	switch(vpp) { +		case 0: +			break; +		case 33: +		case 50: +			if(vcc == vpp) +				reg |= BCSR1_PCCVPP1; +			else +				return 1; +			break; +		case 120: +			if ((vcc == 33) || (vcc == 50)) +				reg |= BCSR1_PCCVPP0; +			else +				return 1; +		default: +			return 1; +	} + +	/* first, turn off all power */ +	out_be32(bcsr_io, in_be32(bcsr_io) & ~(BCSR1_PCCVCC_MASK | BCSR1_PCCVPP_MASK)); + +	/* enable new powersettings */ +	out_be32(bcsr_io, in_be32(bcsr_io) | reg); + +	iounmap(bcsr_io); +	return 0; +} + +#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V + +static void hardware_enable(int slot) +{ +	unsigned *bcsr_io; + +	bcsr_io = ioremap(BCSR1, sizeof(unsigned long)); +	out_be32(bcsr_io, in_be32(bcsr_io) & ~BCSR1_PCCEN); +	iounmap(bcsr_io); +} + +static void hardware_disable(int slot) +{ +	unsigned *bcsr_io; + +	bcsr_io = ioremap(BCSR1, sizeof(unsigned long)); +	out_be32(bcsr_io, in_be32(bcsr_io) |  BCSR1_PCCEN); +	iounmap(bcsr_io);  }  #endif @@ -440,10 +525,10 @@ static int voltage_set(int slot, int vcc, int vpp)  	}  	/* first, turn off all power */ -	out_8(&((u8 *)MBX_CSR2_ADDR), in_8(&((u8 *)MBX_CSR2_ADDR)) & ~(CSR2_VCC_MASK | CSR2_VPP_MASK)); +	out_8((u8 *)MBX_CSR2_ADDR, in_8((u8 *)MBX_CSR2_ADDR) & ~(CSR2_VCC_MASK | CSR2_VPP_MASK));  	/* enable new powersettings */ -	out_8(&((u8 *)MBX_CSR2_ADDR), in_8(&((u8 *)MBX_CSR2_ADDR)) | reg); +	out_8((u8 *)MBX_CSR2_ADDR, in_8((u8 *)MBX_CSR2_ADDR) | reg);  	return 0;  } @@ -823,17 +908,6 @@ static int m8xx_get_status(struct pcmcia_socket *sock, unsigned int *value)  	return 0;  } -static int m8xx_get_socket(struct pcmcia_socket *sock, socket_state_t *state) -{ -	int lsock = container_of(sock, struct socket_info, socket)->slot; -	*state = socket[lsock].state; /* copy the whole structure */ - -	dprintk("GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, " -	      "io_irq %d, csc_mask %#2.2x\n", lsock, state->flags, -	      state->Vcc, state->Vpp, state->io_irq, state->csc_mask); -	return 0; -} -  static int m8xx_set_socket(struct pcmcia_socket *sock, socket_state_t *state)  {  	int lsock = container_of(sock, struct socket_info, socket)->slot; @@ -1023,8 +1097,7 @@ static int m8xx_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)  		if(io->flags & MAP_WRPROT)  			reg |= M8XX_PCMCIA_POR_WRPROT; -		/*if(io->flags & (MAP_16BIT | MAP_AUTOSZ))*/ -		if(io->flags & MAP_16BIT) +		if(io->flags & (MAP_16BIT | MAP_AUTOSZ))  			reg |= M8XX_PCMCIA_POR_16BIT;  		if(io->flags & MAP_ACTIVE) @@ -1169,7 +1242,6 @@ static struct pccard_operations m8xx_services = {  	.init	= m8xx_sock_init,  	.suspend = m8xx_suspend,  	.get_status = m8xx_get_status, -	.get_socket = m8xx_get_socket,  	.set_socket = m8xx_set_socket,  	.set_io_map = m8xx_set_io_map,  	.set_mem_map = m8xx_set_mem_map, @@ -1244,7 +1316,7 @@ static int __init m8xx_init(void)  		socket[i].socket.io_offset = 0;  		socket[i].socket.pci_irq = i  ? 7 : 9;  		socket[i].socket.ops = &m8xx_services; -		socket[i].socket.resource_ops = &pccard_nonstatic_ops; +		socket[i].socket.resource_ops = &pccard_iodyn_ops;  		socket[i].socket.cb_dev = NULL;  		socket[i].socket.dev.dev = &m8xx_device.dev;  	} diff --git a/drivers/pcmcia/pd6729.c b/drivers/pcmcia/pd6729.c index 20642f0e7bfe..f2789afb22b2 100644 --- a/drivers/pcmcia/pd6729.c +++ b/drivers/pcmcia/pd6729.c @@ -304,75 +304,6 @@ static int pd6729_get_status(struct pcmcia_socket *sock, u_int *value)  } -static int pd6729_get_socket(struct pcmcia_socket *sock, socket_state_t *state) -{ -	struct pd6729_socket *socket -			= container_of(sock, struct pd6729_socket, socket); -	unsigned char reg, vcc, vpp; - -	state->flags    = 0; -	state->Vcc      = 0; -	state->Vpp      = 0; -	state->io_irq   = 0; -	state->csc_mask = 0; - -	/* First the power status of the socket */ -	reg = indirect_read(socket, I365_POWER); - -	if (reg & I365_PWR_AUTO) -		state->flags |= SS_PWR_AUTO;  /* Automatic Power Switch */ - -	if (reg & I365_PWR_OUT) -		state->flags |= SS_OUTPUT_ENA; /* Output signals are enabled */ - -	vcc = reg & I365_VCC_MASK;    vpp = reg & I365_VPP1_MASK; - -	if (reg & I365_VCC_5V) { -		state->Vcc = (indirect_read(socket, PD67_MISC_CTL_1) & -			PD67_MC1_VCC_3V) ? 33 : 50; - -		if (vpp == I365_VPP1_5V) { -			if (state->Vcc == 50) -				state->Vpp = 50; -			else -				state->Vpp = 33; -		} -		if (vpp == I365_VPP1_12V) -			state->Vpp = 120; -	} - -	/* Now the IO card, RESET flags and IO interrupt */ -	reg = indirect_read(socket, I365_INTCTL); - -	if ((reg & I365_PC_RESET) == 0) -		state->flags |= SS_RESET; -	if (reg & I365_PC_IOCARD) -		state->flags |= SS_IOCARD; /* This is an IO card */ - -	/* Set the IRQ number */ -	state->io_irq = socket->card_irq; - -	/* Card status change */ -	reg = indirect_read(socket, I365_CSCINT); - -	if (reg & I365_CSC_DETECT) -		state->csc_mask |= SS_DETECT; /* Card detect is enabled */ - -	if (state->flags & SS_IOCARD) {/* IO Cards behave different */ -		if (reg & I365_CSC_STSCHG) -			state->csc_mask |= SS_STSCHG; -	} else { -		if (reg & I365_CSC_BVD1) -			state->csc_mask |= SS_BATDEAD; -		if (reg & I365_CSC_BVD2) -			state->csc_mask |= SS_BATWARN; -		if (reg & I365_CSC_READY) -			state->csc_mask |= SS_READY; -	} - -	return 0; -} -  static int pd6729_set_socket(struct pcmcia_socket *sock, socket_state_t *state)  {  	struct pd6729_socket *socket @@ -640,7 +571,6 @@ static int pd6729_init(struct pcmcia_socket *sock)  static struct pccard_operations pd6729_operations = {  	.init 			= pd6729_init,  	.get_status		= pd6729_get_status, -	.get_socket		= pd6729_get_socket,  	.set_socket		= pd6729_set_socket,  	.set_io_map		= pd6729_set_io_map,  	.set_mem_map		= pd6729_set_mem_map, @@ -704,13 +634,11 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev,  	char configbyte;  	struct pd6729_socket *socket; -	socket = kmalloc(sizeof(struct pd6729_socket) * MAX_SOCKETS, +	socket = kzalloc(sizeof(struct pd6729_socket) * MAX_SOCKETS,  			 GFP_KERNEL);  	if (!socket)  		return -ENOMEM; -	memset(socket, 0, sizeof(struct pd6729_socket) * MAX_SOCKETS); -  	if ((ret = pci_enable_device(dev)))  		goto err_out_free_mem; diff --git a/drivers/pcmcia/pxa2xx_mainstone.c b/drivers/pcmcia/pxa2xx_mainstone.c index 5209d8c7764f..5d957dfe23d9 100644 --- a/drivers/pcmcia/pxa2xx_mainstone.c +++ b/drivers/pcmcia/pxa2xx_mainstone.c @@ -171,10 +171,9 @@ static int __init mst_pcmcia_init(void)  {  	int ret; -	mst_pcmcia_device = kmalloc(sizeof(*mst_pcmcia_device), GFP_KERNEL); +	mst_pcmcia_device = kzalloc(sizeof(*mst_pcmcia_device), GFP_KERNEL);  	if (!mst_pcmcia_device)  		return -ENOMEM; -	memset(mst_pcmcia_device, 0, sizeof(*mst_pcmcia_device));  	mst_pcmcia_device->name = "pxa2xx-pcmcia";  	mst_pcmcia_device->dev.platform_data = &mst_pcmcia_ops; diff --git a/drivers/pcmcia/pxa2xx_sharpsl.c b/drivers/pcmcia/pxa2xx_sharpsl.c index 56c58831e80e..b5fdeec20b15 100644 --- a/drivers/pcmcia/pxa2xx_sharpsl.c +++ b/drivers/pcmcia/pxa2xx_sharpsl.c @@ -264,11 +264,10 @@ static int __init sharpsl_pcmcia_init(void)  	int ret;  	sharpsl_pcmcia_ops.nr=platform_scoop_config->num_devs; -	sharpsl_pcmcia_device = kmalloc(sizeof(*sharpsl_pcmcia_device), GFP_KERNEL); +	sharpsl_pcmcia_device = kzalloc(sizeof(*sharpsl_pcmcia_device), GFP_KERNEL);  	if (!sharpsl_pcmcia_device)  		return -ENOMEM; -	memset(sharpsl_pcmcia_device, 0, sizeof(*sharpsl_pcmcia_device));  	sharpsl_pcmcia_device->name = "pxa2xx-pcmcia";  	sharpsl_pcmcia_device->dev.platform_data = &sharpsl_pcmcia_ops;  	sharpsl_pcmcia_device->dev.parent=platform_scoop_config->devs[0].dev; diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c index 0668384ebc8b..514609369836 100644 --- a/drivers/pcmcia/rsrc_mgr.c +++ b/drivers/pcmcia/rsrc_mgr.c @@ -98,10 +98,12 @@ int pcmcia_adjust_resource_info(adjust_t *adj)  }  EXPORT_SYMBOL(pcmcia_adjust_resource_info); -void pcmcia_validate_mem(struct pcmcia_socket *s) +int pcmcia_validate_mem(struct pcmcia_socket *s)  {  	if (s->resource_ops->validate_mem) -		s->resource_ops->validate_mem(s); +		return s->resource_ops->validate_mem(s); +	/* if there is no callback, we can assume that everything is OK */ +	return 0;  }  EXPORT_SYMBOL(pcmcia_validate_mem); @@ -164,3 +166,105 @@ struct pccard_resource_ops pccard_static_ops = {  	.exit = NULL,  };  EXPORT_SYMBOL(pccard_static_ops); + + +#ifdef CONFIG_PCCARD_IODYN + +static struct resource * +make_resource(unsigned long b, unsigned long n, int flags, char *name) +{ +	struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL); + +	if (res) { +		res->name = name; +		res->start = b; +		res->end = b + n - 1; +		res->flags = flags; +	} +	return res; +} + +struct pcmcia_align_data { +	unsigned long	mask; +	unsigned long	offset; +}; + +static void pcmcia_align(void *align_data, struct resource *res, +			unsigned long size, unsigned long align) +{ +	struct pcmcia_align_data *data = align_data; +	unsigned long start; + +	start = (res->start & ~data->mask) + data->offset; +	if (start < res->start) +		start += data->mask + 1; +	res->start = start; + +#ifdef CONFIG_X86 +        if (res->flags & IORESOURCE_IO) { +                if (start & 0x300) { +                        start = (start + 0x3ff) & ~0x3ff; +                        res->start = start; +                } +        } +#endif + +#ifdef CONFIG_M68K +        if (res->flags & IORESOURCE_IO) { +		if ((res->start + size - 1) >= 1024) +			res->start = res->end; +	} +#endif +} + + +static int iodyn_adjust_io_region(struct resource *res, unsigned long r_start, +				      unsigned long r_end, struct pcmcia_socket *s) +{ +	return adjust_resource(res, r_start, r_end - r_start + 1); +} + + +static struct resource *iodyn_find_io_region(unsigned long base, int num, +		unsigned long align, struct pcmcia_socket *s) +{ +	struct resource *res = make_resource(0, num, IORESOURCE_IO, +					     s->dev.class_id); +	struct pcmcia_align_data data; +	unsigned long min = base; +	int ret; + +	if (align == 0) +		align = 0x10000; + +	data.mask = align - 1; +	data.offset = base & data.mask; + +#ifdef CONFIG_PCI +	if (s->cb_dev) { +		ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 1, +					     min, 0, pcmcia_align, &data); +	} else +#endif +		ret = allocate_resource(&ioport_resource, res, num, min, ~0UL, +					1, pcmcia_align, &data); + +	if (ret != 0) { +		kfree(res); +		res = NULL; +	} +	return res; +} + +struct pccard_resource_ops pccard_iodyn_ops = { +	.validate_mem = NULL, +	.adjust_io_region = iodyn_adjust_io_region, +	.find_io = iodyn_find_io_region, +	.find_mem = NULL, +	.adjust_resource = NULL, +	.init = static_init, +	.exit = NULL, +}; +EXPORT_SYMBOL(pccard_iodyn_ops); + +#endif /* CONFIG_PCCARD_IODYN */ diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c index 00960a379b9c..5301ac60358f 100644 --- a/drivers/pcmcia/rsrc_nonstatic.c +++ b/drivers/pcmcia/rsrc_nonstatic.c @@ -75,10 +75,9 @@ static DECLARE_MUTEX(rsrc_sem);  static struct resource *  make_resource(unsigned long b, unsigned long n, int flags, char *name)  { -	struct resource *res = kmalloc(sizeof(*res), GFP_KERNEL); +	struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL);  	if (res) { -		memset(res, 0, sizeof(*res));  		res->name = name;  		res->start = b;  		res->end = b + n - 1; @@ -200,12 +199,11 @@ static void do_io_probe(struct pcmcia_socket *s, kio_addr_t base, kio_addr_t num  	   base, base+num-1);      /* First, what does a floating port look like? */ -    b = kmalloc(256, GFP_KERNEL); +    b = kzalloc(256, GFP_KERNEL);      if (!b) {              printk(KERN_ERR "do_io_probe: unable to kmalloc 256 bytes");              return;      } -    memset(b, 0, 256);      for (i = base, most = 0; i < base+num; i += 8) {  	res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA IO probe");  	if (!res) @@ -407,69 +405,79 @@ static int do_mem_probe(u_long base, u_long num, struct pcmcia_socket *s)  static u_long inv_probe(struct resource_map *m, struct pcmcia_socket *s)  { -    struct socket_data *s_data = s->resource_data; -    u_long ok; -    if (m == &s_data->mem_db) -	return 0; -    ok = inv_probe(m->next, s); -    if (ok) { -	if (m->base >= 0x100000) -	    sub_interval(&s_data->mem_db, m->base, m->num); -	return ok; -    } -    if (m->base < 0x100000) -	return 0; -    return do_mem_probe(m->base, m->num, s); +	struct socket_data *s_data = s->resource_data; +	u_long ok; +	if (m == &s_data->mem_db) +		return 0; +	ok = inv_probe(m->next, s); +	if (ok) { +		if (m->base >= 0x100000) +			sub_interval(&s_data->mem_db, m->base, m->num); +		return ok; +	} +	if (m->base < 0x100000) +		return 0; +	return do_mem_probe(m->base, m->num, s);  } -static void validate_mem(struct pcmcia_socket *s, unsigned int probe_mask) +static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)  { -    struct resource_map *m, mm; -    static u_char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 }; -    u_long b, i, ok = 0; -    struct socket_data *s_data = s->resource_data; +	struct resource_map *m, mm; +	static unsigned char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 }; +	unsigned long b, i, ok = 0; +	struct socket_data *s_data = s->resource_data; -    /* We do up to four passes through the list */ -    if (probe_mask & MEM_PROBE_HIGH) { -	if (inv_probe(s_data->mem_db.next, s) > 0) -	    return; -	printk(KERN_NOTICE "cs: warning: no high memory space " -	       "available!\n"); -    } -    if ((probe_mask & MEM_PROBE_LOW) == 0) -	return; -    for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) { -	mm = *m; -	/* Only probe < 1 MB */ -	if (mm.base >= 0x100000) continue; -	if ((mm.base | mm.num) & 0xffff) { -	    ok += do_mem_probe(mm.base, mm.num, s); -	    continue; +	/* We do up to four passes through the list */ +	if (probe_mask & MEM_PROBE_HIGH) { +		if (inv_probe(s_data->mem_db.next, s) > 0) +			return 0; +		printk(KERN_NOTICE "cs: warning: no high memory space " +		       "available!\n"); +		return -ENODEV;  	} -	/* Special probe for 64K-aligned block */ -	for (i = 0; i < 4; i++) { -	    b = order[i] << 12; -	    if ((b >= mm.base) && (b+0x10000 <= mm.base+mm.num)) { -		if (ok >= mem_limit) -		    sub_interval(&s_data->mem_db, b, 0x10000); -		else -		    ok += do_mem_probe(b, 0x10000, s); -	    } + +	for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) { +		mm = *m; +		/* Only probe < 1 MB */ +		if (mm.base >= 0x100000) +			continue; +		if ((mm.base | mm.num) & 0xffff) { +			ok += do_mem_probe(mm.base, mm.num, s); +			continue; +		} +		/* Special probe for 64K-aligned block */ +		for (i = 0; i < 4; i++) { +			b = order[i] << 12; +			if ((b >= mm.base) && (b+0x10000 <= mm.base+mm.num)) { +				if (ok >= mem_limit) +					sub_interval(&s_data->mem_db, b, 0x10000); +				else +					ok += do_mem_probe(b, 0x10000, s); +			} +		}  	} -    } + +	if (ok > 0) +		return 0; + +	return -ENODEV;  }  #else /* CONFIG_PCMCIA_PROBE */ -static void validate_mem(struct pcmcia_socket *s, unsigned int probe_mask) +static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)  {  	struct resource_map *m, mm;  	struct socket_data *s_data = s->resource_data; +	unsigned long ok = 0;  	for (m = s_data->mem_db.next; m != &s_data->mem_db; m = mm.next) {  		mm = *m; -		do_mem_probe(mm.base, mm.num, s); +		ok += do_mem_probe(mm.base, mm.num, s);  	} +	if (ok > 0) +		return 0; +	return -ENODEV;  }  #endif /* CONFIG_PCMCIA_PROBE */ @@ -478,27 +486,30 @@ static void validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)  /*   * Locking note: Must be called with skt_sem held!   */ -static void pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s) +static int pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s)  {  	struct socket_data *s_data = s->resource_data; -	if (probe_mem) { -		unsigned int probe_mask; +	unsigned int probe_mask = MEM_PROBE_LOW; +	int ret = 0; -		down(&rsrc_sem); +	if (!probe_mem) +		return 0; -		probe_mask = MEM_PROBE_LOW; -		if (s->features & SS_CAP_PAGE_REGS) -			probe_mask = MEM_PROBE_HIGH; +	down(&rsrc_sem); -		if (probe_mask & ~s_data->rsrc_mem_probe) { +	if (s->features & SS_CAP_PAGE_REGS) +		probe_mask = MEM_PROBE_HIGH; + +	if (probe_mask & ~s_data->rsrc_mem_probe) { +		if (s->state & SOCKET_PRESENT) +			ret = validate_mem(s, probe_mask); +		if (!ret)  			s_data->rsrc_mem_probe |= probe_mask; +	} -			if (s->state & SOCKET_PRESENT) -				validate_mem(s, probe_mask); -		} +	up(&rsrc_sem); -		up(&rsrc_sem); -	} +	return ret;  }  struct pcmcia_align_data { @@ -837,10 +848,9 @@ static int nonstatic_init(struct pcmcia_socket *s)  {  	struct socket_data *data; -	data = kmalloc(sizeof(struct socket_data), GFP_KERNEL); +	data = kzalloc(sizeof(struct socket_data), GFP_KERNEL);  	if (!data)  		return -ENOMEM; -	memset(data, 0, sizeof(struct socket_data));  	data->mem_db.next = &data->mem_db;  	data->io_db.next = &data->io_db; diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c index 9e7ccd8a4321..ea7d9ca160b2 100644 --- a/drivers/pcmcia/soc_common.c +++ b/drivers/pcmcia/soc_common.c @@ -297,25 +297,6 @@ soc_common_pcmcia_get_status(struct pcmcia_socket *sock, unsigned int *status)  /* - * Implements the get_socket() operation for the in-kernel PCMCIA - * service (formerly SS_GetSocket in Card Services). Not a very - * exciting routine. - * - * Returns: 0 - */ -static int -soc_common_pcmcia_get_socket(struct pcmcia_socket *sock, socket_state_t *state) -{ -	struct soc_pcmcia_socket *skt = to_soc_pcmcia_socket(sock); - -	debug(skt, 2, "\n"); - -	*state = skt->cs_state; - -	return 0; -} - -/*   * Implements the set_socket() operation for the in-kernel PCMCIA   * service (formerly SS_SetSocket in Card Services). We more or   * less punt all of this work and let the kernel handle the details @@ -528,7 +509,6 @@ static struct pccard_operations soc_common_pcmcia_operations = {  	.init			= soc_common_pcmcia_sock_init,  	.suspend		= soc_common_pcmcia_suspend,  	.get_status		= soc_common_pcmcia_get_status, -	.get_socket		= soc_common_pcmcia_get_socket,  	.set_socket		= soc_common_pcmcia_set_socket,  	.set_io_map		= soc_common_pcmcia_set_io_map,  	.set_mem_map		= soc_common_pcmcia_set_mem_map, @@ -665,13 +645,12 @@ int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops  	down(&soc_pcmcia_sockets_lock); -	sinfo = kmalloc(SKT_DEV_INFO_SIZE(nr), GFP_KERNEL); +	sinfo = kzalloc(SKT_DEV_INFO_SIZE(nr), GFP_KERNEL);  	if (!sinfo) {  		ret = -ENOMEM;  		goto out;  	} -	memset(sinfo, 0, SKT_DEV_INFO_SIZE(nr));  	sinfo->nskt = nr;  	/* diff --git a/drivers/pcmcia/socket_sysfs.c b/drivers/pcmcia/socket_sysfs.c index 4a3150a7854c..7a7744662d54 100644 --- a/drivers/pcmcia/socket_sysfs.c +++ b/drivers/pcmcia/socket_sysfs.c @@ -42,35 +42,28 @@  static ssize_t pccard_show_type(struct class_device *dev, char *buf)  { -	int val;  	struct pcmcia_socket *s = to_socket(dev);  	if (!(s->state & SOCKET_PRESENT))  		return -ENODEV; -	s->ops->get_status(s, &val); -	if (val & SS_CARDBUS) +	if (s->state & SOCKET_CARDBUS)  		return sprintf(buf, "32-bit\n"); -	if (val & SS_DETECT) -		return sprintf(buf, "16-bit\n"); -	return sprintf(buf, "invalid\n"); +	return sprintf(buf, "16-bit\n");  } -static CLASS_DEVICE_ATTR(card_type, 0400, pccard_show_type, NULL); +static CLASS_DEVICE_ATTR(card_type, 0444, pccard_show_type, NULL);  static ssize_t pccard_show_voltage(struct class_device *dev, char *buf)  { -	int val;  	struct pcmcia_socket *s = to_socket(dev);  	if (!(s->state & SOCKET_PRESENT))  		return -ENODEV; -	s->ops->get_status(s, &val); -	if (val & SS_3VCARD) -		return sprintf(buf, "3.3V\n"); -	if (val & SS_XVCARD) -		return sprintf(buf, "X.XV\n"); -	return sprintf(buf, "5.0V\n"); +	if (s->socket.Vcc) +		return sprintf(buf, "%d.%dV\n", s->socket.Vcc / 10, +			       s->socket.Vcc % 10); +	return sprintf(buf, "X.XV\n");  } -static CLASS_DEVICE_ATTR(card_voltage, 0400, pccard_show_voltage, NULL); +static CLASS_DEVICE_ATTR(card_voltage, 0444, pccard_show_voltage, NULL);  static ssize_t pccard_show_vpp(struct class_device *dev, char *buf)  { @@ -79,7 +72,7 @@ static ssize_t pccard_show_vpp(struct class_device *dev, char *buf)  		return -ENODEV;  	return sprintf(buf, "%d.%dV\n", s->socket.Vpp / 10, s->socket.Vpp % 10);  } -static CLASS_DEVICE_ATTR(card_vpp, 0400, pccard_show_vpp, NULL); +static CLASS_DEVICE_ATTR(card_vpp, 0444, pccard_show_vpp, NULL);  static ssize_t pccard_show_vcc(struct class_device *dev, char *buf)  { @@ -88,7 +81,7 @@ static ssize_t pccard_show_vcc(struct class_device *dev, char *buf)  		return -ENODEV;  	return sprintf(buf, "%d.%dV\n", s->socket.Vcc / 10, s->socket.Vcc % 10);  } -static CLASS_DEVICE_ATTR(card_vcc, 0400, pccard_show_vcc, NULL); +static CLASS_DEVICE_ATTR(card_vcc, 0444, pccard_show_vcc, NULL);  static ssize_t pccard_store_insert(struct class_device *dev, const char *buf, size_t count) @@ -292,10 +285,9 @@ static ssize_t pccard_store_cis(struct kobject *kobj, char *buf, loff_t off, siz  	if (!(s->state & SOCKET_PRESENT))  		return -ENODEV; -	cis = kmalloc(sizeof(cisdump_t), GFP_KERNEL); +	cis = kzalloc(sizeof(cisdump_t), GFP_KERNEL);  	if (!cis)  		return -ENOMEM; -	memset(cis, 0, sizeof(cisdump_t));  	cis->Length = count + 1;  	memcpy(cis->Data, buf, count); diff --git a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c index e31263864377..73bad1d5cb23 100644 --- a/drivers/pcmcia/tcic.c +++ b/drivers/pcmcia/tcic.c @@ -181,13 +181,6 @@ static void tcic_setl(u_char reg, u_int data)      outw(data >> 16, tcic_base+reg+2);  } -static u_char tcic_aux_getb(u_short reg) -{ -    u_char mode = (tcic_getb(TCIC_MODE) & TCIC_MODE_PGMMASK) | reg; -    tcic_setb(TCIC_MODE, mode); -    return tcic_getb(TCIC_AUX); -} -  static void tcic_aux_setb(u_short reg, u_char data)  {      u_char mode = (tcic_getb(TCIC_MODE) & TCIC_MODE_PGMMASK) | reg; @@ -641,59 +634,6 @@ static int tcic_get_status(struct pcmcia_socket *sock, u_int *value)      debug(1, "GetStatus(%d) = %#2.2x\n", psock, *value);      return 0;  } /* tcic_get_status */ -   -/*====================================================================*/ - -static int tcic_get_socket(struct pcmcia_socket *sock, socket_state_t *state) -{ -    u_short psock = container_of(sock, struct tcic_socket, socket)->psock; -    u_char reg; -    u_short scf1, scf2; -     -    tcic_setl(TCIC_ADDR, (psock << TCIC_ADDR_SS_SHFT) -	      | TCIC_ADDR_INDREG | TCIC_SCF1(psock)); -    scf1 = tcic_getw(TCIC_DATA); -    state->flags = (scf1 & TCIC_SCF1_IOSTS) ? SS_IOCARD : 0; -    state->flags |= (scf1 & TCIC_SCF1_DMA_MASK) ? SS_DMA_MODE : 0; -    state->flags |= (scf1 & TCIC_SCF1_SPKR) ? SS_SPKR_ENA : 0; -    if (tcic_getb(TCIC_SCTRL) & TCIC_SCTRL_ENA) -	state->flags |= SS_OUTPUT_ENA; -    state->io_irq = scf1 & TCIC_SCF1_IRQ_MASK; -    if (state->io_irq == 1) state->io_irq = 11; - -    reg = tcic_getb(TCIC_PWR); -    state->Vcc = state->Vpp = 0; -    if (reg & TCIC_PWR_VCC(psock)) { -	if (reg & TCIC_PWR_VPP(psock)) -	    state->Vcc = 50; -	else -	    state->Vcc = state->Vpp = 50; -    } else { -	if (reg & TCIC_PWR_VPP(psock)) { -	    state->Vcc = 50; -	    state->Vpp = 120; -	} -    } -    reg = tcic_aux_getb(TCIC_AUX_ILOCK); -    state->flags |= (reg & TCIC_ILOCK_CRESET) ? SS_RESET : 0; - -    /* Card status change interrupt mask */ -    tcic_setw(TCIC_ADDR, TCIC_SCF2(psock)); -    scf2 = tcic_getw(TCIC_DATA); -    state->csc_mask = (scf2 & TCIC_SCF2_MCD) ? 0 : SS_DETECT; -    if (state->flags & SS_IOCARD) { -	state->csc_mask |= (scf2 & TCIC_SCF2_MLBAT1) ? 0 : SS_STSCHG; -    } else { -	state->csc_mask |= (scf2 & TCIC_SCF2_MLBAT1) ? 0 : SS_BATDEAD; -	state->csc_mask |= (scf2 & TCIC_SCF2_MLBAT2) ? 0 : SS_BATWARN; -	state->csc_mask |= (scf2 & TCIC_SCF2_MRDY) ? 0 : SS_READY; -    } - -    debug(1, "GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, " -	  "io_irq %d, csc_mask %#2.2x\n", psock, state->flags, -	  state->Vcc, state->Vpp, state->io_irq, state->csc_mask); -    return 0; -} /* tcic_get_socket */  /*====================================================================*/ @@ -874,7 +814,6 @@ static int tcic_init(struct pcmcia_socket *s)  static struct pccard_operations tcic_operations = {  	.init		   = tcic_init,  	.get_status	   = tcic_get_status, -	.get_socket	   = tcic_get_socket,  	.set_socket	   = tcic_set_socket,  	.set_io_map	   = tcic_set_io_map,  	.set_mem_map	   = tcic_set_mem_map, diff --git a/drivers/pcmcia/ti113x.h b/drivers/pcmcia/ti113x.h index 539b5cd1a598..d5b4ff74462e 100644 --- a/drivers/pcmcia/ti113x.h +++ b/drivers/pcmcia/ti113x.h @@ -873,7 +873,7 @@ static int ti1250_override(struct yenta_socket *socket)   * Some fixup code to make everybody happy (TM).   */ -#ifdef CONFIG_CARDBUS +#ifdef CONFIG_YENTA_ENE_TUNE  /**   * set/clear various test bits:   * Defaults to clear the bit. @@ -937,7 +937,7 @@ static int ene_override(struct yenta_socket *socket)  }  #else  #  define ene_override ti1250_override -#endif +#endif /* !CONFIG_YENTA_ENE_TUNE */  #endif /* _LINUX_TI113X_H */ diff --git a/drivers/pcmcia/vrc4171_card.c b/drivers/pcmcia/vrc4171_card.c index 38a028c725d4..24c547ef512b 100644 --- a/drivers/pcmcia/vrc4171_card.c +++ b/drivers/pcmcia/vrc4171_card.c @@ -301,75 +301,6 @@ static int pccard_get_status(struct pcmcia_socket *sock, u_int *value)  	return 0;  } -static inline u_char get_Vcc_value(uint8_t voltage) -{ -	switch (voltage) { -	case VCC_STATUS_3V: -		return 33; -	case VCC_STATUS_5V: -		return 50; -	default: -		break; -	} - -	return 0; -} - -static inline u_char get_Vpp_value(uint8_t power, u_char Vcc) -{ -	if ((power & 0x03) == 0x01 || (power & 0x03) == 0x02) -		return Vcc; - -	return 0; -} - -static int pccard_get_socket(struct pcmcia_socket *sock, socket_state_t *state) -{ -	unsigned int slot; -	uint8_t power, voltage, control, cscint; - -	if (sock == NULL || sock->sock >= CARD_MAX_SLOTS || state == NULL) -		return -EINVAL; - -	slot = sock->sock; - -	power = exca_read_byte(slot, I365_POWER); -	voltage = exca_read_byte(slot, CARD_VOLTAGE_SELECT); - -	state->Vcc = get_Vcc_value(voltage); -	state->Vpp = get_Vpp_value(power, state->Vcc); - -	state->flags = 0; -	if (power & POWER_ENABLE) -		state->flags |= SS_PWR_AUTO; -	if (power & I365_PWR_OUT) -		state->flags |= SS_OUTPUT_ENA; - -	control = exca_read_byte(slot, I365_INTCTL); -	if (control & I365_PC_IOCARD) -		state->flags |= SS_IOCARD; -	if (!(control & I365_PC_RESET)) -		state->flags |= SS_RESET; - -        cscint = exca_read_byte(slot, I365_CSCINT); -	state->csc_mask = 0; -	if (state->flags & SS_IOCARD) { -		if (cscint & I365_CSC_STSCHG) -			state->flags |= SS_STSCHG; -	} else { -		if (cscint & I365_CSC_BVD1) -			state->csc_mask |= SS_BATDEAD; -		if (cscint & I365_CSC_BVD2) -			state->csc_mask |= SS_BATWARN; -	} -	if (cscint & I365_CSC_READY) -		state->csc_mask |= SS_READY; -	if (cscint & I365_CSC_DETECT) -		state->csc_mask |= SS_DETECT; - -	return 0; -} -  static inline uint8_t set_Vcc_value(u_char Vcc)  {  	switch (Vcc) { @@ -551,7 +482,6 @@ static int pccard_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map  static struct pccard_operations vrc4171_pccard_operations = {  	.init			= pccard_init,  	.get_status		= pccard_get_status, -	.get_socket		= pccard_get_socket,  	.set_socket		= pccard_set_socket,  	.set_io_map		= pccard_set_io_map,  	.set_mem_map		= pccard_set_mem_map, diff --git a/drivers/pcmcia/vrc4173_cardu.c b/drivers/pcmcia/vrc4173_cardu.c index db91259dc50e..1b277d2c1c96 100644 --- a/drivers/pcmcia/vrc4173_cardu.c +++ b/drivers/pcmcia/vrc4173_cardu.c @@ -198,48 +198,6 @@ static int cardu_get_status(unsigned int sock, u_int *value)  	return 0;  } -static inline u_char get_Vcc_value(uint8_t val) -{ -	switch (val & VCC_MASK) { -	case VCC_3V: -		return 33; -	case VCC_5V: -		return 50; -	} - -	return 0; -} - -static inline u_char get_Vpp_value(uint8_t val) -{ -	switch (val & VPP_MASK) { -	case VPP_12V: -		return 120; -	case VPP_VCC: -		return get_Vcc_value(val); -	} - -	return 0; -} - -static int cardu_get_socket(unsigned int sock, socket_state_t *state) -{ -	vrc4173_socket_t *socket = &cardu_sockets[sock]; -	uint8_t val; - -	val = exca_readb(socket, PWR_CNT); -	state->Vcc = get_Vcc_value(val); -	state->Vpp = get_Vpp_value(val); -	state->flags = 0; -	if (val & CARD_OUT_EN) state->flags |= SS_OUTPUT_ENA; - -	val = exca_readb(socket, INT_GEN_CNT); -	if (!(val & CARD_REST0)) state->flags |= SS_RESET; -	if (val & CARD_TYPE_IO) state->flags |= SS_IOCARD; - -	return 0; -} -  static inline uint8_t set_Vcc_value(u_char Vcc)  {  	switch (Vcc) { @@ -431,7 +389,6 @@ static struct pccard_operations cardu_operations = {  	.register_callback	= cardu_register_callback,  	.inquire_socket		= cardu_inquire_socket,  	.get_status		= cardu_get_status, -	.get_socket		= cardu_get_socket,  	.set_socket		= cardu_set_socket,  	.get_io_map		= cardu_get_io_map,  	.set_io_map		= cardu_set_io_map, diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c index ec6ab65f0872..4145eb83b9b6 100644 --- a/drivers/pcmcia/yenta_socket.c +++ b/drivers/pcmcia/yenta_socket.c @@ -49,7 +49,13 @@ MODULE_PARM_DESC(pwr_irqs_off, "Force IRQs off during power-on of slot. Use only  #define to_cycles(ns)	((ns)/120)  #define to_ns(cycles)	((cycles)*120) +/** + * yenta PCI irq probing. + * currently only used in the TI/EnE initialization code + */ +#ifdef CONFIG_YENTA_TI  static int yenta_probe_cb_irq(struct yenta_socket *socket); +#endif  static unsigned int override_bios; @@ -224,95 +230,6 @@ static int yenta_get_status(struct pcmcia_socket *sock, unsigned int *value)  	return 0;  } -static void yenta_get_power(struct yenta_socket *socket, socket_state_t *state) -{ -	if (!(cb_readl(socket, CB_SOCKET_STATE) & CB_CBCARD) && -	    (socket->flags & YENTA_16BIT_POWER_EXCA)) { -		u8 reg, vcc, vpp; - -		reg = exca_readb(socket, I365_POWER); -		vcc = reg & I365_VCC_MASK; -		vpp = reg & I365_VPP1_MASK; -		state->Vcc = state->Vpp = 0; - -		if (socket->flags & YENTA_16BIT_POWER_DF) { -			if (vcc == I365_VCC_3V) -				state->Vcc = 33; -			if (vcc == I365_VCC_5V) -				state->Vcc = 50; -			if (vpp == I365_VPP1_5V) -				state->Vpp = state->Vcc; -			if (vpp == I365_VPP1_12V) -				state->Vpp = 120; -		} else { -			if (reg & I365_VCC_5V) { -				state->Vcc = 50; -				if (vpp == I365_VPP1_5V) -					state->Vpp = 50; -				if (vpp == I365_VPP1_12V) -					state->Vpp = 120; -			} -		} -	} else { -		u32 control; - -		control = cb_readl(socket, CB_SOCKET_CONTROL); - -		switch (control & CB_SC_VCC_MASK) { -		case CB_SC_VCC_5V: state->Vcc = 50; break; -		case CB_SC_VCC_3V: state->Vcc = 33; break; -		default: state->Vcc = 0; -		} - -		switch (control & CB_SC_VPP_MASK) { -		case CB_SC_VPP_12V: state->Vpp = 120; break; -		case CB_SC_VPP_5V: state->Vpp = 50; break; -		case CB_SC_VPP_3V: state->Vpp = 33; break; -		default: state->Vpp = 0; -		} -	} -} - -static int yenta_get_socket(struct pcmcia_socket *sock, socket_state_t *state) -{ -	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket); -	u8 reg; -	u32 control; - -	control = cb_readl(socket, CB_SOCKET_CONTROL); - -	yenta_get_power(socket, state); -	state->io_irq = socket->io_irq; - -	if (cb_readl(socket, CB_SOCKET_STATE) & CB_CBCARD) { -		u16 bridge = config_readw(socket, CB_BRIDGE_CONTROL); -		if (bridge & CB_BRIDGE_CRST) -			state->flags |= SS_RESET; -		return 0; -	} - -	/* 16-bit card state.. */ -	reg = exca_readb(socket, I365_POWER); -	state->flags = (reg & I365_PWR_AUTO) ? SS_PWR_AUTO : 0; -	state->flags |= (reg & I365_PWR_OUT) ? SS_OUTPUT_ENA : 0; - -	reg = exca_readb(socket, I365_INTCTL); -	state->flags |= (reg & I365_PC_RESET) ? 0 : SS_RESET; -	state->flags |= (reg & I365_PC_IOCARD) ? SS_IOCARD : 0; - -	reg = exca_readb(socket, I365_CSCINT); -	state->csc_mask = (reg & I365_CSC_DETECT) ? SS_DETECT : 0; -	if (state->flags & SS_IOCARD) { -		state->csc_mask |= (reg & I365_CSC_STSCHG) ? SS_STSCHG : 0; -	} else { -		state->csc_mask |= (reg & I365_CSC_BVD1) ? SS_BATDEAD : 0; -		state->csc_mask |= (reg & I365_CSC_BVD2) ? SS_BATWARN : 0; -		state->csc_mask |= (reg & I365_CSC_READY) ? SS_READY : 0; -	} - -	return 0; -} -  static void yenta_set_power(struct yenta_socket *socket, socket_state_t *state)  {  	/* some birdges require to use the ExCA registers to power 16bit cards */ @@ -531,6 +448,9 @@ static irqreturn_t yenta_interrupt(int irq, void *dev_id, struct pt_regs *regs)  	csc = exca_readb(socket, I365_CSC); +	if (!(cb_event || csc)) +		return IRQ_NONE; +  	events = (cb_event & (CB_CD1EVENT | CB_CD2EVENT)) ? SS_DETECT : 0 ;  	events |= (csc & I365_CSC_DETECT) ? SS_DETECT : 0;  	if (exca_readb(socket, I365_INTCTL) & I365_PC_IOCARD) { @@ -544,10 +464,7 @@ static irqreturn_t yenta_interrupt(int irq, void *dev_id, struct pt_regs *regs)  	if (events)  		pcmcia_parse_events(&socket->socket, events); -	if (cb_event || csc) -		return IRQ_HANDLED; - -	return IRQ_NONE; +	return IRQ_HANDLED;  }  static void yenta_interrupt_wrapper(unsigned long data) @@ -828,17 +745,24 @@ static struct pccard_operations yenta_socket_operations = {  	.init			= yenta_sock_init,  	.suspend		= yenta_sock_suspend,  	.get_status		= yenta_get_status, -	.get_socket		= yenta_get_socket,  	.set_socket		= yenta_set_socket,  	.set_io_map		= yenta_set_io_map,  	.set_mem_map		= yenta_set_mem_map,  }; +#ifdef CONFIG_YENTA_TI  #include "ti113x.h" +#endif +#ifdef CONFIG_YENTA_RICOH  #include "ricoh.h" +#endif +#ifdef CONFIG_YENTA_TOSHIBA  #include "topic.h" +#endif +#ifdef CONFIG_YENTA_O2  #include "o2micro.h" +#endif  enum {  	CARDBUS_TYPE_DEFAULT = -1, @@ -858,6 +782,7 @@ enum {   * initialization sequences etc details. List them here..   */  static struct cardbus_type cardbus_type[] = { +#ifdef CONFIG_YENTA_TI  	[CARDBUS_TYPE_TI]	= {  		.override	= ti_override,  		.save_state	= ti_save_state, @@ -882,27 +807,36 @@ static struct cardbus_type cardbus_type[] = {  		.restore_state	= ti_restore_state,  		.sock_init	= ti_init,  	}, +#endif +#ifdef CONFIG_YENTA_RICOH  	[CARDBUS_TYPE_RICOH]	= {  		.override	= ricoh_override,  		.save_state	= ricoh_save_state,  		.restore_state	= ricoh_restore_state,  	}, +#endif +#ifdef CONFIG_YENTA_TOSHIBA  	[CARDBUS_TYPE_TOPIC95]	= {  		.override	= topic95_override,  	},  	[CARDBUS_TYPE_TOPIC97]	= {  		.override	= topic97_override,  	}, +#endif +#ifdef CONFIG_YENTA_O2  	[CARDBUS_TYPE_O2MICRO]	= {  		.override	= o2micro_override,  		.restore_state	= o2micro_restore_state,  	}, +#endif +#ifdef CONFIG_YENTA_TI  	[CARDBUS_TYPE_ENE]	= {  		.override	= ene_override,  		.save_state	= ti_save_state,  		.restore_state	= ti_restore_state,  		.sock_init	= ti_init,  	}, +#endif  }; @@ -948,6 +882,12 @@ static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mas  } +/** + * yenta PCI irq probing. + * currently only used in the TI/EnE initialization code + */ +#ifdef CONFIG_YENTA_TI +  /* interrupt handler, only used during probing */  static irqreturn_t yenta_probe_handler(int irq, void *dev_id, struct pt_regs *regs)  { @@ -1000,6 +940,7 @@ static int yenta_probe_cb_irq(struct yenta_socket *socket)  	return (int) socket->probe_status;  } +#endif /* CONFIG_YENTA_TI */  /* @@ -1078,10 +1019,9 @@ static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_i  		return -ENODEV;  	} -	socket = kmalloc(sizeof(struct yenta_socket), GFP_KERNEL); +	socket = kzalloc(sizeof(struct yenta_socket), GFP_KERNEL);  	if (!socket)  		return -ENOMEM; -	memset(socket, 0, sizeof(*socket));  	/* prepare pcmcia_socket */  	socket->socket.ops = ¥ta_socket_operations; @@ -1263,6 +1203,7 @@ static struct pci_device_id yenta_table [] = {  	 * advanced overrides instead.  (I can't get the  	 * data sheets for these devices. --rmk)  	 */ +#ifdef CONFIG_YENTA_TI  	CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1210, TI),  	CB_ID(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1130, TI113X), @@ -1305,18 +1246,25 @@ static struct pci_device_id yenta_table [] = {  	CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1225, ENE),  	CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1410, ENE),  	CB_ID(PCI_VENDOR_ID_ENE, PCI_DEVICE_ID_ENE_1420, ENE), +#endif /* CONFIG_YENTA_TI */ +#ifdef CONFIG_YENTA_RICOH  	CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C465, RICOH),  	CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C466, RICOH),  	CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C475, RICOH),  	CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, RICOH),  	CB_ID(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C478, RICOH), +#endif +#ifdef CONFIG_YENTA_TOSHIBA  	CB_ID(PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_TOSHIBA_TOPIC95, TOPIC95),  	CB_ID(PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_TOSHIBA_TOPIC97, TOPIC97),  	CB_ID(PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_TOSHIBA_TOPIC100, TOPIC97), +#endif +#ifdef CONFIG_YENTA_O2  	CB_ID(PCI_VENDOR_ID_O2, PCI_ANY_ID, O2MICRO), +#endif  	/* match any cardbus bridge */  	CB_ID(PCI_ANY_ID, PCI_ANY_ID, DEFAULT), diff --git a/drivers/scsi/pcmcia/aha152x_stub.c b/drivers/scsi/pcmcia/aha152x_stub.c index 7c5306499832..0c9edb7051f4 100644 --- a/drivers/scsi/pcmcia/aha152x_stub.c +++ b/drivers/scsi/pcmcia/aha152x_stub.c @@ -95,27 +95,21 @@ typedef struct scsi_info_t {  } scsi_info_t;  static void aha152x_release_cs(dev_link_t *link); -static int aha152x_event(event_t event, int priority, -			 event_callback_args_t *args); - -static dev_link_t *aha152x_attach(void); -static void aha152x_detach(dev_link_t *); +static void aha152x_detach(struct pcmcia_device *p_dev); +static void aha152x_config_cs(dev_link_t *link);  static dev_link_t *dev_list; -static dev_info_t dev_info = "aha152x_cs"; -static dev_link_t *aha152x_attach(void) +static int aha152x_attach(struct pcmcia_device *p_dev)  {      scsi_info_t *info; -    client_reg_t client_reg;      dev_link_t *link; -    int ret;      DEBUG(0, "aha152x_attach()\n");      /* Create new SCSI device */      info = kmalloc(sizeof(*info), GFP_KERNEL); -    if (!info) return NULL; +    if (!info) return -ENOMEM;      memset(info, 0, sizeof(*info));      link = &info->link; link->priv = info; @@ -129,26 +123,20 @@ static dev_link_t *aha152x_attach(void)      link->conf.IntType = INT_MEMORY_AND_IO;      link->conf.Present = PRESENT_OPTION; -    /* Register with Card Services */ -    link->next = dev_list; -    dev_list = link; -    client_reg.dev_info = &dev_info; -    client_reg.Version = 0x0210; -    client_reg.event_callback_args.client_data = link; -    ret = pcmcia_register_client(&link->handle, &client_reg); -    if (ret != 0) { -	cs_error(link->handle, RegisterClient, ret); -	aha152x_detach(link); -	return NULL; -    } -     -    return link; +    link->handle = p_dev; +    p_dev->instance = link; + +    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; +    aha152x_config_cs(link); + +    return 0;  } /* aha152x_attach */  /*====================================================================*/ -static void aha152x_detach(dev_link_t *link) +static void aha152x_detach(struct pcmcia_device *p_dev)  { +    dev_link_t *link = dev_to_instance(p_dev);      dev_link_t **linkp;      DEBUG(0, "aha152x_detach(0x%p)\n", link); @@ -162,9 +150,6 @@ static void aha152x_detach(dev_link_t *link)      if (link->state & DEV_CONFIG)  	aha152x_release_cs(link); -    if (link->handle) -	pcmcia_deregister_client(link->handle); -          /* Unlink device structure, free bits */      *linkp = link->next;      kfree(link->priv); @@ -272,44 +257,31 @@ static void aha152x_release_cs(dev_link_t *link)  	link->state &= ~DEV_CONFIG;  } -static int aha152x_event(event_t event, int priority, -			 event_callback_args_t *args) +static int aha152x_suspend(struct pcmcia_device *dev)  { -    dev_link_t *link = args->client_data; -    scsi_info_t *info = link->priv; -     -    DEBUG(0, "aha152x_event(0x%06x)\n", event); -     -    switch (event) { -    case CS_EVENT_CARD_REMOVAL: -	link->state &= ~DEV_PRESENT; -	if (link->state & DEV_CONFIG) -	    aha152x_release_cs(link); -	break; -    case CS_EVENT_CARD_INSERTION: -	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; -	aha152x_config_cs(link); -	break; -    case CS_EVENT_PM_SUSPEND: +	dev_link_t *link = dev_to_instance(dev); +  	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: +		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; -	/* 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); +		Scsi_Cmnd tmp; +		pcmcia_request_configuration(link->handle, &link->conf); +		tmp.device->host = info->host; +		aha152x_host_reset(&tmp);  	} -	break; -    } -    return 0; + +	return 0;  }  static struct pcmcia_device_id aha152x_ids[] = { @@ -327,10 +299,11 @@ static struct pcmcia_driver aha152x_cs_driver = {  	.drv		= {  		.name	= "aha152x_cs",  	}, -	.attach		= aha152x_attach, -	.event		= aha152x_event, -	.detach		= aha152x_detach, +	.probe		= aha152x_attach, +	.remove		= aha152x_detach,  	.id_table       = aha152x_ids, +	.suspend	= aha152x_suspend, +	.resume		= aha152x_resume,  };  static int __init init_aha152x_cs(void) diff --git a/drivers/scsi/pcmcia/fdomain_stub.c b/drivers/scsi/pcmcia/fdomain_stub.c index db8f5cd85ffe..788c58d805f3 100644 --- a/drivers/scsi/pcmcia/fdomain_stub.c +++ b/drivers/scsi/pcmcia/fdomain_stub.c @@ -80,29 +80,19 @@ typedef struct scsi_info_t {  static void fdomain_release(dev_link_t *link); -static int fdomain_event(event_t event, int priority, -			event_callback_args_t *args); +static void fdomain_detach(struct pcmcia_device *p_dev); +static void fdomain_config(dev_link_t *link); -static dev_link_t *fdomain_attach(void); -static void fdomain_detach(dev_link_t *); - - -static dev_link_t *dev_list = NULL; - -static dev_info_t dev_info = "fdomain_cs"; - -static dev_link_t *fdomain_attach(void) +static int fdomain_attach(struct pcmcia_device *p_dev)  {      scsi_info_t *info; -    client_reg_t client_reg;      dev_link_t *link; -    int ret; -     +      DEBUG(0, "fdomain_attach()\n");      /* Create new SCSI device */      info = kmalloc(sizeof(*info), GFP_KERNEL); -    if (!info) return NULL; +    if (!info) return -ENOMEM;      memset(info, 0, sizeof(*info));      link = &info->link; link->priv = info;      link->io.NumPorts1 = 0x10; @@ -115,46 +105,27 @@ static dev_link_t *fdomain_attach(void)      link->conf.IntType = INT_MEMORY_AND_IO;      link->conf.Present = PRESENT_OPTION; -    /* Register with Card Services */ -    link->next = dev_list; -    dev_list = link; -    client_reg.dev_info = &dev_info; -    client_reg.Version = 0x0210; -    client_reg.event_callback_args.client_data = link; -    ret = pcmcia_register_client(&link->handle, &client_reg); -    if (ret != 0) { -	cs_error(link->handle, RegisterClient, ret); -	fdomain_detach(link); -	return NULL; -    } -     -    return link; +    link->handle = p_dev; +    p_dev->instance = link; + +    link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; +    fdomain_config(link); + +    return 0;  } /* fdomain_attach */  /*====================================================================*/ -static void fdomain_detach(dev_link_t *link) +static void fdomain_detach(struct pcmcia_device *p_dev)  { -    dev_link_t **linkp; +	dev_link_t *link = dev_to_instance(p_dev); -    DEBUG(0, "fdomain_detach(0x%p)\n", link); -     -    /* Locate device structure */ -    for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) -	if (*linkp == link) break; -    if (*linkp == NULL) -	return; +	DEBUG(0, "fdomain_detach(0x%p)\n", link); -    if (link->state & DEV_CONFIG) -	fdomain_release(link); +	if (link->state & DEV_CONFIG) +		fdomain_release(link); -    if (link->handle) -	pcmcia_deregister_client(link->handle); -     -    /* Unlink device structure, free bits */ -    *linkp = link->next; -    kfree(link->priv); -     +	kfree(link->priv);  } /* fdomain_detach */  /*====================================================================*/ @@ -256,43 +227,29 @@ static void fdomain_release(dev_link_t *link)  /*====================================================================*/ -static int fdomain_event(event_t event, int priority, -			event_callback_args_t *args) +static int fdomain_suspend(struct pcmcia_device *dev)  { -    dev_link_t *link = args->client_data; +	dev_link_t *link = dev_to_instance(dev); -    DEBUG(1, "fdomain_event(0x%06x)\n", event); -     -    switch (event) { -    case CS_EVENT_CARD_REMOVAL: -	link->state &= ~DEV_PRESENT; -	if (link->state & DEV_CONFIG) -	    fdomain_release(link); -	break; -    case CS_EVENT_CARD_INSERTION: -	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; -	fdomain_config(link); -	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: +		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; -	/* Fall through... */ -    case CS_EVENT_CARD_RESET:  	if (link->state & DEV_CONFIG) { -	    pcmcia_request_configuration(link->handle, &link->conf); -	    fdomain_16x0_bus_reset(NULL); +		pcmcia_request_configuration(link->handle, &link->conf); +		fdomain_16x0_bus_reset(NULL);  	} -	break; -    } -    return 0; -} /* fdomain_event */ +	return 0; +}  static struct pcmcia_device_id fdomain_ids[] = {  	PCMCIA_DEVICE_PROD_ID12("IBM Corp.", "SCSI PCMCIA Card", 0xe3736c88, 0x859cad20), @@ -307,10 +264,11 @@ static struct pcmcia_driver fdomain_cs_driver = {  	.drv		= {  		.name	= "fdomain_cs",  	}, -	.attach		= fdomain_attach, -	.event		= fdomain_event, -	.detach		= fdomain_detach, +	.probe		= fdomain_attach, +	.remove		= fdomain_detach,  	.id_table       = fdomain_ids, +	.suspend	= fdomain_suspend, +	.resume		= fdomain_resume,  };  static int __init init_fdomain_cs(void) @@ -321,7 +279,6 @@ static int __init init_fdomain_cs(void)  static void __exit exit_fdomain_cs(void)  {  	pcmcia_unregister_driver(&fdomain_cs_driver); -	BUG_ON(dev_list != NULL);  }  module_init(init_fdomain_cs); diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c index 050ea13ff80b..9e3ab3fd5355 100644 --- a/drivers/scsi/pcmcia/nsp_cs.c +++ b/drivers/scsi/pcmcia/nsp_cs.c @@ -104,9 +104,6 @@ static struct scsi_host_template nsp_driver_template = {  #endif  }; -static dev_link_t *dev_list = NULL; -static dev_info_t dev_info  = {"nsp_cs"}; -  static nsp_hw_data nsp_data_base; /* attach <-> detect glue */ @@ -1596,19 +1593,17 @@ static int nsp_eh_host_reset(Scsi_Cmnd *SCpnt)      configure the card at this point -- we wait until we receive a      card insertion event.  ======================================================================*/ -static dev_link_t *nsp_cs_attach(void) +static int nsp_cs_attach(struct pcmcia_device *p_dev)  {  	scsi_info_t  *info; -	client_reg_t  client_reg;  	dev_link_t   *link; -	int	      ret;  	nsp_hw_data  *data = &nsp_data_base;  	nsp_dbg(NSP_DEBUG_INIT, "in");  	/* Create new SCSI device */  	info = kmalloc(sizeof(*info), GFP_KERNEL); -	if (info == NULL) { return NULL; } +	if (info == NULL) { return -ENOMEM; }  	memset(info, 0, sizeof(*info));  	link = &info->link;  	link->priv = info; @@ -1636,23 +1631,14 @@ static dev_link_t *nsp_cs_attach(void)  	link->conf.IntType	 = INT_MEMORY_AND_IO;  	link->conf.Present	 = PRESENT_OPTION; +	link->handle = p_dev; +	p_dev->instance = link; -	/* Register with Card Services */ -	link->next               = dev_list; -	dev_list                 = link; -	client_reg.dev_info	 = &dev_info; -	client_reg.Version	 = 0x0210; -	client_reg.event_callback_args.client_data = link; -	ret = pcmcia_register_client(&link->handle, &client_reg); -	if (ret != CS_SUCCESS) { -		cs_error(link->handle, RegisterClient, ret); -		nsp_cs_detach(link); -		return NULL; -	} - +	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; +	nsp_cs_config(link);  	nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link); -	return link; +	return 0;  } /* nsp_cs_attach */ @@ -1662,35 +1648,19 @@ static dev_link_t *nsp_cs_attach(void)      structures are freed.  Otherwise, the structures will be freed      when the device is released.  ======================================================================*/ -static void nsp_cs_detach(dev_link_t *link) +static void nsp_cs_detach(struct pcmcia_device *p_dev)  { -	dev_link_t **linkp; +	dev_link_t *link = dev_to_instance(p_dev);  	nsp_dbg(NSP_DEBUG_INIT, "in, link=0x%p", link); -	/* Locate device structure */ -	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) { -		if (*linkp == link) { -			break; -		} -	} -	if (*linkp == NULL) { -		return; -	} - -	if (link->state & DEV_CONFIG) +	if (link->state & DEV_CONFIG) { +		((scsi_info_t *)link->priv)->stop = 1;  		nsp_cs_release(link); - -	/* Break the link with Card Services */ -	if (link->handle) { -		pcmcia_deregister_client(link->handle);  	} -	/* Unlink device structure, free bits */ -	*linkp = link->next;  	kfree(link->priv);  	link->priv = NULL; -  } /* nsp_cs_detach */ @@ -2021,99 +1991,58 @@ static void nsp_cs_release(dev_link_t *link)  #endif  } /* nsp_cs_release */ -/*====================================================================== - -    The card status event handler.  Mostly, this schedules other -    stuff to run after an event is received.  A CARD_REMOVAL event -    also sets some flags to discourage the net drivers from trying -    to talk to the card any more. - -    When a CARD_REMOVAL event is received, we immediately set a flag -    to block future accesses to this device.  All the functions that -    actually access the device should check this flag to make sure -    the card is still present. - -======================================================================*/ -static int nsp_cs_event(event_t		       event, -			int		       priority, -			event_callback_args_t *args) +static int nsp_cs_suspend(struct pcmcia_device *dev)  { -	dev_link_t  *link = args->client_data; +	dev_link_t *link = dev_to_instance(dev);  	scsi_info_t *info = link->priv;  	nsp_hw_data *data; -	nsp_dbg(NSP_DEBUG_INIT, "in, event=0x%08x", event); +	link->state |= DEV_SUSPEND; -	switch (event) { -	case CS_EVENT_CARD_REMOVAL: -		nsp_dbg(NSP_DEBUG_INIT, "event: remove"); -		link->state &= ~DEV_PRESENT; -		if (link->state & DEV_CONFIG) { -			((scsi_info_t *)link->priv)->stop = 1; -			nsp_cs_release(link); -		} -		break; +	nsp_dbg(NSP_DEBUG_INIT, "event: suspend"); -	case CS_EVENT_CARD_INSERTION: -		nsp_dbg(NSP_DEBUG_INIT, "event: insert"); -		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,68)) -		info->bus    =  args->bus; -#endif -		nsp_cs_config(link); -		break; +	if (info->host != NULL) { +		nsp_msg(KERN_INFO, "clear SDTR status"); -	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"); +		data = (nsp_hw_data *)info->host->hostdata; -		if (info->host != NULL) { -			nsp_msg(KERN_INFO, "clear SDTR status"); +		nsphw_init_sync(data); +	} -			data = (nsp_hw_data *)info->host->hostdata; +	info->stop = 1; -			nsphw_init_sync(data); -		} +	if (link->state & DEV_CONFIG) +		pcmcia_release_configuration(link->handle); -		info->stop = 1; -		if (link->state & DEV_CONFIG) { -			pcmcia_release_configuration(link->handle); -		} -		break; +	return 0; +} -	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; +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; -		if (info->host != NULL) { -			nsp_msg(KERN_INFO, "reset host and bus"); +	nsp_dbg(NSP_DEBUG_INIT, "event: resume"); -			data = (nsp_hw_data *)info->host->hostdata; +	link->state &= ~DEV_SUSPEND; -			nsphw_init   (data); -			nsp_bus_reset(data); -		} +	if (link->state & DEV_CONFIG) +		pcmcia_request_configuration(link->handle, &link->conf); -		break; +	info->stop = 0; -	default: -		nsp_dbg(NSP_DEBUG_INIT, "event: unknown"); -		break; +	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);  	} -	nsp_dbg(NSP_DEBUG_INIT, "end"); +  	return 0; -} /* nsp_cs_event */ +}  /*======================================================================*   *	module entry point @@ -2136,10 +2065,11 @@ static struct pcmcia_driver nsp_driver = {  	.drv		= {  		.name	= "nsp_cs",  	}, -	.attach		= nsp_cs_attach, -	.event		= nsp_cs_event, -	.detach		= nsp_cs_detach, +	.probe		= nsp_cs_attach, +	.remove		= nsp_cs_detach,  	.id_table	= nsp_cs_ids, +	.suspend	= nsp_cs_suspend, +	.resume		= nsp_cs_resume,  };  #endif @@ -2171,7 +2101,6 @@ static void __exit nsp_cs_exit(void)  #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68))  	pcmcia_unregister_driver(&nsp_driver); -	BUG_ON(dev_list != NULL);  #else  	unregister_pcmcia_driver(&dev_info);  	/* XXX: this really needs to move into generic code.. */ diff --git a/drivers/scsi/pcmcia/nsp_cs.h b/drivers/scsi/pcmcia/nsp_cs.h index f8b943082717..b66b140a745e 100644 --- a/drivers/scsi/pcmcia/nsp_cs.h +++ b/drivers/scsi/pcmcia/nsp_cs.h @@ -296,11 +296,9 @@ typedef struct _nsp_hw_data {   */  /* Card service functions */ -static dev_link_t *nsp_cs_attach (void); -static void        nsp_cs_detach (dev_link_t *link); +static void        nsp_cs_detach (struct pcmcia_device *p_dev);  static void        nsp_cs_release(dev_link_t *link);  static void        nsp_cs_config (dev_link_t *link); -static int         nsp_cs_event  (event_t event, int priority, event_callback_args_t *args);  /* Linux SCSI subsystem specific functions */  static struct Scsi_Host *nsp_detect     (struct scsi_host_template *sht); diff --git a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c index bb091a45a880..dce7e687fd4a 100644 --- a/drivers/scsi/pcmcia/qlogic_stub.c +++ b/drivers/scsi/pcmcia/qlogic_stub.c @@ -98,15 +98,8 @@ typedef struct scsi_info_t {  } scsi_info_t;  static void qlogic_release(dev_link_t *link); -static int qlogic_event(event_t event, int priority, event_callback_args_t * args); - -static dev_link_t *qlogic_attach(void); -static void qlogic_detach(dev_link_t *); - - -static dev_link_t *dev_list = NULL; - -static dev_info_t dev_info = "qlogic_cs"; +static void qlogic_detach(struct pcmcia_device *p_dev); +static void qlogic_config(dev_link_t * link);  static struct Scsi_Host *qlogic_detect(struct scsi_host_template *host,  				dev_link_t *link, int qbase, int qlirq) @@ -163,19 +156,17 @@ free_scsi_host:  err:  	return NULL;  } -static dev_link_t *qlogic_attach(void) +static int qlogic_attach(struct pcmcia_device *p_dev)  {  	scsi_info_t *info; -	client_reg_t client_reg;  	dev_link_t *link; -	int ret;  	DEBUG(0, "qlogic_attach()\n");  	/* Create new SCSI device */  	info = kmalloc(sizeof(*info), GFP_KERNEL);  	if (!info) -		return NULL; +		return -ENOMEM;  	memset(info, 0, sizeof(*info));  	link = &info->link;  	link->priv = info; @@ -189,45 +180,26 @@ static dev_link_t *qlogic_attach(void)  	link->conf.IntType = INT_MEMORY_AND_IO;  	link->conf.Present = PRESENT_OPTION; -	/* Register with Card Services */ -	link->next = dev_list; -	dev_list = link; -	client_reg.dev_info = &dev_info; -	client_reg.Version = 0x0210; -	client_reg.event_callback_args.client_data = link; -	ret = pcmcia_register_client(&link->handle, &client_reg); -	if (ret != 0) { -		cs_error(link->handle, RegisterClient, ret); -		qlogic_detach(link); -		return NULL; -	} +	link->handle = p_dev; +	p_dev->instance = link; -	return link; +	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; +	qlogic_config(link); + +	return 0;  }				/* qlogic_attach */  /*====================================================================*/ -static void qlogic_detach(dev_link_t * link) +static void qlogic_detach(struct pcmcia_device *p_dev)  { -	dev_link_t **linkp; +	dev_link_t *link = dev_to_instance(p_dev);  	DEBUG(0, "qlogic_detach(0x%p)\n", link); -	/* Locate device structure */ -	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) -		if (*linkp == link) -			break; -	if (*linkp == NULL) -		return; -  	if (link->state & DEV_CONFIG)  		qlogic_release(link); -	if (link->handle) -		pcmcia_deregister_client(link->handle); - -	/* Unlink device structure, free bits */ -	*linkp = link->next;  	kfree(link->priv);  }				/* qlogic_detach */ @@ -349,48 +321,39 @@ static void qlogic_release(dev_link_t *link)  /*====================================================================*/ -static int qlogic_event(event_t event, int priority, event_callback_args_t * args) +static int qlogic_suspend(struct pcmcia_device *dev)  { -	dev_link_t *link = args->client_data; - -	DEBUG(1, "qlogic_event(0x%06x)\n", event); - -	switch (event) { -	case CS_EVENT_CARD_REMOVAL: -		link->state &= ~DEV_PRESENT; -		if (link->state & DEV_CONFIG) -			qlogic_release(link); -		break; -	case CS_EVENT_CARD_INSERTION: -		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; -		qlogic_config(link); -		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); +	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);  		} -		break; +		/* Ugggglllyyyy!!! */ +		qlogicfas408_bus_reset(NULL);  	} +  	return 0; -}				/* qlogic_event */ +}  static struct pcmcia_device_id qlogic_ids[] = {  	PCMCIA_DEVICE_PROD_ID12("EIger Labs", "PCMCIA-to-SCSI Adapter", 0x88395fa7, 0x33b7a5e6), @@ -419,10 +382,11 @@ static struct pcmcia_driver qlogic_cs_driver = {  	.drv		= {  	.name		= "qlogic_cs",  	}, -	.attach		= qlogic_attach, -	.event		= qlogic_event, -	.detach		= qlogic_detach, +	.probe		= qlogic_attach, +	.remove		= qlogic_detach,  	.id_table       = qlogic_ids, +	.suspend	= qlogic_suspend, +	.resume		= qlogic_resume,  };  static int __init init_qlogic_cs(void) @@ -433,7 +397,6 @@ static int __init init_qlogic_cs(void)  static void __exit exit_qlogic_cs(void)  {  	pcmcia_unregister_driver(&qlogic_cs_driver); -	BUG_ON(dev_list != NULL);  }  MODULE_AUTHOR("Tom Zerucha, Michael Griffith"); diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c index 98b64b2aa8ee..3a4dd6f5b81f 100644 --- a/drivers/scsi/pcmcia/sym53c500_cs.c +++ b/drivers/scsi/pcmcia/sym53c500_cs.c @@ -228,15 +228,6 @@ enum Phase {  /* ================================================================== */ -/* -*  Global (within this module) variables other than -*  sym53c500_driver_template (the scsi_host_template). -*/ -static dev_link_t *dev_list; -static dev_info_t dev_info = "sym53c500_cs"; - -/* ================================================================== */ -  static void  chip_init(int io_port)  { @@ -872,96 +863,70 @@ cs_failed:  	return;  } /* SYM53C500_config */ -static int -SYM53C500_event(event_t event, int priority, event_callback_args_t *args) +static int sym53c500_suspend(struct pcmcia_device *dev)  { -	dev_link_t *link = args->client_data; -	struct scsi_info_t *info = link->priv; +	dev_link_t *link = dev_to_instance(dev); -	DEBUG(1, "SYM53C500_event(0x%06x)\n", event); +	link->state |= DEV_SUSPEND; +	if (link->state & DEV_CONFIG) +		pcmcia_release_configuration(link->handle); -	switch (event) { -	case CS_EVENT_CARD_REMOVAL: -		link->state &= ~DEV_PRESENT; -		if (link->state & DEV_CONFIG) -			SYM53C500_release(link); -		break; -	case CS_EVENT_CARD_INSERTION: -		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; -		SYM53C500_config(link); -		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); +	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);  		} -		break; +		/* +		 *  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; -} /* SYM53C500_event */ +}  static void -SYM53C500_detach(dev_link_t *link) +SYM53C500_detach(struct pcmcia_device *p_dev)  { -	dev_link_t **linkp; +	dev_link_t *link = dev_to_instance(p_dev);  	DEBUG(0, "SYM53C500_detach(0x%p)\n", link); -	/* Locate device structure */ -	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) -		if (*linkp == link) -			break; -	if (*linkp == NULL) -		return; -  	if (link->state & DEV_CONFIG)  		SYM53C500_release(link); -	if (link->handle) -		pcmcia_deregister_client(link->handle); - -	/* Unlink device structure, free bits. */ -	*linkp = link->next;  	kfree(link->priv);  	link->priv = NULL;  } /* SYM53C500_detach */ -static dev_link_t * -SYM53C500_attach(void) +static int +SYM53C500_attach(struct pcmcia_device *p_dev)  {  	struct scsi_info_t *info; -	client_reg_t client_reg;  	dev_link_t *link; -	int ret;  	DEBUG(0, "SYM53C500_attach()\n");  	/* Create new SCSI device */  	info = kmalloc(sizeof(*info), GFP_KERNEL);  	if (!info) -		return NULL; +		return -ENOMEM;  	memset(info, 0, sizeof(*info));  	link = &info->link;  	link->priv = info; @@ -975,20 +940,13 @@ SYM53C500_attach(void)  	link->conf.IntType = INT_MEMORY_AND_IO;  	link->conf.Present = PRESENT_OPTION; -	/* Register with Card Services */ -	link->next = dev_list; -	dev_list = link; -	client_reg.dev_info = &dev_info; -	client_reg.Version = 0x0210; -	client_reg.event_callback_args.client_data = link; -	ret = pcmcia_register_client(&link->handle, &client_reg); -	if (ret != 0) { -		cs_error(link->handle, RegisterClient, ret); -		SYM53C500_detach(link); -		return NULL; -	} +	link->handle = p_dev; +	p_dev->instance = link; + +	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; +	SYM53C500_config(link); -	return link; +	return 0;  } /* SYM53C500_attach */  MODULE_AUTHOR("Bob Tracy <rct@frus.com>"); @@ -1008,10 +966,11 @@ static struct pcmcia_driver sym53c500_cs_driver = {  	.drv		= {  		.name	= "sym53c500_cs",  	}, -	.attach		= SYM53C500_attach, -	.event		= SYM53C500_event, -	.detach		= SYM53C500_detach, +	.probe		= SYM53C500_attach, +	.remove		= SYM53C500_detach,  	.id_table       = sym53c500_ids, +	.suspend	= sym53c500_suspend, +	.resume		= sym53c500_resume,  };  static int __init diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c index 7ce0c7e66d37..96969cb960a9 100644 --- a/drivers/serial/serial_cs.c +++ b/drivers/serial/serial_cs.c @@ -114,15 +114,7 @@ struct serial_cfg_mem {  static void serial_config(dev_link_t * link); -static int serial_event(event_t event, int priority, -			event_callback_args_t * args); -static dev_info_t dev_info = "serial_cs"; - -static dev_link_t *serial_attach(void); -static void serial_detach(dev_link_t *); - -static dev_link_t *dev_list = NULL;  /*====================================================================== @@ -159,8 +151,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;  	if (link->state & DEV_CONFIG) { @@ -173,10 +166,13 @@ static void serial_suspend(dev_link_t *link)  		if (!info->slave)  			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;  	if (DEV_OK(link)) { @@ -189,6 +185,8 @@ static void serial_resume(dev_link_t *link)  		for (i = 0; i < info->ndev; i++)  			serial8250_resume_port(info->line[i]);  	} + +	return 0;  }  /*====================================================================== @@ -199,19 +197,17 @@ static void serial_resume(dev_link_t *link)  ======================================================================*/ -static dev_link_t *serial_attach(void) +static int serial_probe(struct pcmcia_device *p_dev)  {  	struct serial_info *info; -	client_reg_t client_reg;  	dev_link_t *link; -	int ret;  	DEBUG(0, "serial_attach()\n");  	/* Create new serial device */  	info = kmalloc(sizeof (*info), GFP_KERNEL);  	if (!info) -		return NULL; +		return -ENOMEM;  	memset(info, 0, sizeof (*info));  	link = &info->link;  	link->priv = info; @@ -227,20 +223,12 @@ static dev_link_t *serial_attach(void)  	}  	link->conf.IntType = INT_MEMORY_AND_IO; -	/* Register with Card Services */ -	link->next = dev_list; -	dev_list = link; -	client_reg.dev_info = &dev_info; -	client_reg.Version = 0x0210; -	client_reg.event_callback_args.client_data = link; -	ret = pcmcia_register_client(&link->handle, &client_reg); -	if (ret != CS_SUCCESS) { -		cs_error(link->handle, RegisterClient, ret); -		serial_detach(link); -		return NULL; -	} +	link->handle = p_dev; +	p_dev->instance = link; +	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; +	serial_config(link); -	return link; +	return 0;  }  /*====================================================================== @@ -252,21 +240,13 @@ static dev_link_t *serial_attach(void)  ======================================================================*/ -static void serial_detach(dev_link_t * link) +static void serial_detach(struct pcmcia_device *p_dev)  { +	dev_link_t *link = dev_to_instance(p_dev);  	struct serial_info *info = link->priv; -	dev_link_t **linkp; -	int ret;  	DEBUG(0, "serial_detach(0x%p)\n", link); -	/* Locate device structure */ -	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) -		if (*linkp == link) -			break; -	if (*linkp == NULL) -		return; -  	/*  	 * Ensure any outstanding scheduled tasks are completed.  	 */ @@ -277,14 +257,7 @@ static void serial_detach(dev_link_t * link)  	 */  	serial_remove(link); -	if (link->handle) { -		ret = pcmcia_deregister_client(link->handle); -		if (ret != CS_SUCCESS) -			cs_error(link->handle, DeregisterClient, ret); -	} - -	/* Unlink device structure, free bits */ -	*linkp = link->next; +	/* free bits */  	kfree(info);  } @@ -718,54 +691,6 @@ void serial_config(dev_link_t * link)  	kfree(cfg_mem);  } -/*====================================================================== - -    The card status event handler.  Mostly, this schedules other -    stuff to run after an event is received.  A CARD_REMOVAL event -    also sets some flags to discourage the serial drivers from -    talking to the ports. -     -======================================================================*/ - -static int -serial_event(event_t event, int priority, event_callback_args_t * args) -{ -	dev_link_t *link = args->client_data; -	struct serial_info *info = link->priv; - -	DEBUG(1, "serial_event(0x%06x)\n", event); - -	switch (event) { -	case CS_EVENT_CARD_REMOVAL: -		serial_remove(link); -		break; - -	case CS_EVENT_CARD_INSERTION: -		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; -		serial_config(link); -		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; -} -  static struct pcmcia_device_id serial_ids[] = {  	PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0057, 0x0021),  	PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0089, 0x110a), @@ -877,10 +802,11 @@ static struct pcmcia_driver serial_cs_driver = {  	.drv		= {  		.name	= "serial_cs",  	}, -	.attach		= serial_attach, -	.event		= serial_event, -	.detach		= serial_detach, +	.probe		= serial_probe, +	.remove		= serial_detach,  	.id_table	= serial_ids, +	.suspend	= serial_suspend, +	.resume		= serial_resume,  };  static int __init init_serial_cs(void) @@ -891,7 +817,6 @@ static int __init init_serial_cs(void)  static void __exit exit_serial_cs(void)  {  	pcmcia_unregister_driver(&serial_cs_driver); -	BUG_ON(dev_list != NULL);  }  module_init(init_serial_cs); diff --git a/drivers/telephony/ixj_pcmcia.c b/drivers/telephony/ixj_pcmcia.c index 57c0c6e3fbed..d3a7b0c3d38b 100644 --- a/drivers/telephony/ixj_pcmcia.c +++ b/drivers/telephony/ixj_pcmcia.c @@ -34,24 +34,19 @@ typedef struct ixj_info_t {  	struct ixj *port;  } ixj_info_t; -static dev_link_t *ixj_attach(void); -static void ixj_detach(dev_link_t *); +static void ixj_detach(struct pcmcia_device *p_dev);  static void ixj_config(dev_link_t * link);  static void ixj_cs_release(dev_link_t * link); -static int ixj_event(event_t event, int priority, event_callback_args_t * args); -static dev_info_t dev_info = "ixj_cs"; -static dev_link_t *dev_list = NULL; -static dev_link_t *ixj_attach(void) +static int ixj_attach(struct pcmcia_device *p_dev)  { -	client_reg_t client_reg;  	dev_link_t *link; -	int ret; +  	DEBUG(0, "ixj_attach()\n");  	/* Create new ixj device */  	link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);  	if (!link) -		return NULL; +		return -ENOMEM;  	memset(link, 0, sizeof(struct dev_link_t));  	link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;  	link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; @@ -61,44 +56,29 @@ static dev_link_t *ixj_attach(void)  	link->priv = kmalloc(sizeof(struct ixj_info_t), GFP_KERNEL);  	if (!link->priv) {  		kfree(link); -		return NULL; +		return -ENOMEM;  	}  	memset(link->priv, 0, sizeof(struct ixj_info_t)); -	/* Register with Card Services */ -	link->next = dev_list; -	dev_list = link; -	client_reg.dev_info = &dev_info; -	client_reg.Version = 0x0210; -	client_reg.event_callback_args.client_data = link; -	ret = pcmcia_register_client(&link->handle, &client_reg); -	if (ret != CS_SUCCESS) { -		cs_error(link->handle, RegisterClient, ret); -		ixj_detach(link); -		return NULL; -	} -	return link; + +	link->handle = p_dev; +	p_dev->instance = link; + +	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; +	ixj_config(link); + +	return 0;  } -static void ixj_detach(dev_link_t * link) +static void ixj_detach(struct pcmcia_device *p_dev)  { -	dev_link_t **linkp; -	int ret; +	dev_link_t *link = dev_to_instance(p_dev); +  	DEBUG(0, "ixj_detach(0x%p)\n", link); -	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) -		if (*linkp == link) -			break; -	if (*linkp == NULL) -		return; +  	link->state &= ~DEV_RELEASE_PENDING;  	if (link->state & DEV_CONFIG)  		ixj_cs_release(link); -	if (link->handle) { -		ret = pcmcia_deregister_client(link->handle); -		if (ret != CS_SUCCESS) -			cs_error(link->handle, DeregisterClient, ret); -	} -	/* Unlink device structure, free bits */ -	*linkp = link->next; +          kfree(link->priv);          kfree(link);  } @@ -255,37 +235,25 @@ static void ixj_cs_release(dev_link_t *link)  	link->state &= ~DEV_CONFIG;  } -static int ixj_event(event_t event, int priority, event_callback_args_t * args) +static int ixj_suspend(struct pcmcia_device *dev)  { -	dev_link_t *link = args->client_data; -	DEBUG(1, "ixj_event(0x%06x)\n", event); -	switch (event) { -	case CS_EVENT_CARD_REMOVAL: -		link->state &= ~DEV_PRESENT; -		if (link->state & DEV_CONFIG) { -			link->state |= DEV_RELEASE_PENDING; -			ixj_cs_release(link); -		} -		break; -	case CS_EVENT_CARD_INSERTION: -		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; -		ixj_config(link); -		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; -	} +	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;  } @@ -300,10 +268,11 @@ static struct pcmcia_driver ixj_driver = {  	.drv		= {  		.name	= "ixj_cs",  	}, -	.attach		= ixj_attach, -	.event		= ixj_event, -	.detach		= ixj_detach, +	.probe		= ixj_attach, +	.remove		= ixj_detach,  	.id_table	= ixj_ids, +	.suspend	= ixj_suspend, +	.resume		= ixj_resume,  };  static int __init ixj_pcmcia_init(void) @@ -314,7 +283,6 @@ static int __init ixj_pcmcia_init(void)  static void ixj_pcmcia_exit(void)  {  	pcmcia_unregister_driver(&ixj_driver); -	BUG_ON(dev_list != NULL);  }  module_init(ixj_pcmcia_init); diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c index 5056b7459994..466384d7c79f 100644 --- a/drivers/usb/host/sl811_cs.c +++ b/drivers/usb/host/sl811_cs.c @@ -66,13 +66,13 @@ module_param(pc_debug, int, 0644);  static const char driver_name[DEV_NAME_LEN]  = "sl811_cs"; -static dev_link_t *dev_list = NULL; -  typedef struct local_info_t {  	dev_link_t		link;  	dev_node_t		node;  } local_info_t; +static void sl811_cs_release(dev_link_t * link); +  /*====================================================================*/  static void release_platform_dev(struct device * dev) @@ -138,26 +138,16 @@ static int sl811_hc_init(struct device *parent, ioaddr_t base_addr, int irq)  /*====================================================================*/ -static void sl811_cs_detach(dev_link_t *link) +static void sl811_cs_detach(struct pcmcia_device *p_dev)  { -	dev_link_t **linkp; +	dev_link_t *link = dev_to_instance(p_dev);  	DBG(0, "sl811_cs_detach(0x%p)\n", link); -	/* Locate device structure */ -	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) { -		if (*linkp == link) -			break; -	} -	if (*linkp == NULL) -		return; - -	/* Break the link with Card Services */ -	if (link->handle) -		pcmcia_deregister_client(link->handle); +	link->state &= ~DEV_PRESENT; +	if (link->state & DEV_CONFIG) +		sl811_cs_release(link); -	/* Unlink device structure, and free it */ -	*linkp = link->next;  	/* This points to the parent local_info_t struct */  	kfree(link->priv);  } @@ -167,13 +157,6 @@ static void sl811_cs_release(dev_link_t * link)  	DBG(0, "sl811_cs_release(0x%p)\n", link); -	if (link->open) { -		DBG(1, "sl811_cs: release postponed, '%s' still open\n", -		    link->dev->dev_name); -		link->state |= DEV_STALE_CONFIG; -		return; -	} -  	/* Unlink the device chain */  	link->dev = NULL; @@ -184,9 +167,6 @@ static void sl811_cs_release(dev_link_t * link)  	if (link->irq.AssignedIRQ)  		pcmcia_release_irq(link->handle, &link->irq);  	link->state &= ~DEV_CONFIG; - -	if (link->state & DEV_STALE_LINK) -		sl811_cs_detach(link);  }  static void sl811_cs_config(dev_link_t *link) @@ -323,55 +303,36 @@ cs_failed:  	}  } -static int -sl811_cs_event(event_t event, int priority, event_callback_args_t *args) +static int sl811_suspend(struct pcmcia_device *dev)  { -	dev_link_t *link = args->client_data; +	dev_link_t *link = dev_to_instance(dev); -	DBG(1, "sl811_cs_event(0x%06x)\n", event); +	link->state |= DEV_SUSPEND; +	if (link->state & DEV_CONFIG) +		pcmcia_release_configuration(link->handle); -	switch (event) { -	case CS_EVENT_CARD_REMOVAL: -		link->state &= ~DEV_PRESENT; -		if (link->state & DEV_CONFIG) -			sl811_cs_release(link); -		break; +	return 0; +} -	case CS_EVENT_CARD_INSERTION: -		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; -		sl811_cs_config(link); -		break; +static int sl811_resume(struct pcmcia_device *dev) +{ +	dev_link_t *link = dev_to_instance(dev); -	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; +	link->state &= ~DEV_SUSPEND; +	if (link->state & DEV_CONFIG) +		pcmcia_request_configuration(link->handle, &link->conf); -	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;  } -static dev_link_t *sl811_cs_attach(void) +static int sl811_cs_attach(struct pcmcia_device *p_dev)  {  	local_info_t *local;  	dev_link_t *link; -	client_reg_t client_reg; -	int ret;  	local = kmalloc(sizeof(local_info_t), GFP_KERNEL);  	if (!local) -		return NULL; +		return -ENOMEM;  	memset(local, 0, sizeof(local_info_t));  	link = &local->link;  	link->priv = local; @@ -385,21 +346,13 @@ static dev_link_t *sl811_cs_attach(void)  	link->conf.Vcc = 33;  	link->conf.IntType = INT_MEMORY_AND_IO; -	/* Register with Card Services */ -	link->next = dev_list; -	dev_list = link; -	client_reg.dev_info = (dev_info_t *) &driver_name; -	client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE; -	client_reg.Version = 0x0210; -	client_reg.event_callback_args.client_data = link; -	ret = pcmcia_register_client(&link->handle, &client_reg); -	if (ret != CS_SUCCESS) { -		cs_error(link->handle, RegisterClient, ret); -		sl811_cs_detach(link); -		return NULL; -	} +	link->handle = p_dev; +	p_dev->instance = link; -	return link; +	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; +	sl811_cs_config(link); + +	return 0;  }  static struct pcmcia_device_id sl811_ids[] = { @@ -413,10 +366,11 @@ static struct pcmcia_driver sl811_cs_driver = {  	.drv		= {  		.name	= (char *)driver_name,  	}, -	.attach		= sl811_cs_attach, -	.event		= sl811_cs_event, -	.detach		= sl811_cs_detach, +	.probe		= sl811_cs_attach, +	.remove		= sl811_cs_detach,  	.id_table	= sl811_ids, +	.suspend	= sl811_suspend, +	.resume		= sl811_resume,  };  /*====================================================================*/ diff --git a/include/pcmcia/cs.h b/include/pcmcia/cs.h index 2cab39f49eb2..52660f32663d 100644 --- a/include/pcmcia/cs.h +++ b/include/pcmcia/cs.h @@ -382,7 +382,6 @@ enum service {  struct pcmcia_socket;  int pcmcia_access_configuration_register(struct pcmcia_device *p_dev, conf_reg_t *reg); -int pcmcia_deregister_client(struct pcmcia_device *p_dev);  int pcmcia_get_configuration_info(struct pcmcia_device *p_dev, config_info_t *config);  int pcmcia_get_first_window(window_handle_t *win, win_req_t *req);  int pcmcia_get_next_window(window_handle_t *win, win_req_t *req); @@ -390,7 +389,6 @@ int pcmcia_get_status(struct pcmcia_device *p_dev, cs_status_t *status);  int pcmcia_get_mem_page(window_handle_t win, memreq_t *req);  int pcmcia_map_mem_page(window_handle_t win, memreq_t *req);  int pcmcia_modify_configuration(struct pcmcia_device *p_dev, modconf_t *mod); -int pcmcia_register_client(client_handle_t *handle, client_reg_t *req);  int pcmcia_release_configuration(struct pcmcia_device *p_dev);  int pcmcia_release_io(struct pcmcia_device *p_dev, io_req_t *req);  int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req); diff --git a/include/pcmcia/ds.h b/include/pcmcia/ds.h index cb8b6e6ce66c..8e2a96396478 100644 --- a/include/pcmcia/ds.h +++ b/include/pcmcia/ds.h @@ -133,10 +133,12 @@ typedef struct dev_link_t {  struct pcmcia_socket;  struct pcmcia_driver { -	dev_link_t		*(*attach)(void); -	int (*event)		(event_t event, int priority, -				 event_callback_args_t *); -	void			(*detach)(dev_link_t *); +	int (*probe)		(struct pcmcia_device *dev); +	void (*remove)		(struct pcmcia_device *dev); + +	int (*suspend)		(struct pcmcia_device *dev); +	int (*resume)		(struct pcmcia_device *dev); +  	struct module		*owner;  	struct pcmcia_device_id	*id_table;  	struct device_driver	drv; @@ -164,7 +166,6 @@ struct pcmcia_device {  	/* deprecated, a cleaned up version will be moved into this  	   struct soon */  	dev_link_t		*instance; -	event_callback_args_t 	event_callback_args;  	u_int			state;  	/* information about this device */ @@ -193,6 +194,8 @@ struct pcmcia_device {  #define handle_to_pdev(handle) (handle)  #define handle_to_dev(handle) (handle->dev) +#define dev_to_instance(dev) (dev->instance) +  /* error reporting */  void cs_error(client_handle_t handle, int func, int ret); diff --git a/include/pcmcia/ss.h b/include/pcmcia/ss.h index e788bbc5657d..2889a69a7a8f 100644 --- a/include/pcmcia/ss.h +++ b/include/pcmcia/ss.h @@ -118,16 +118,14 @@ struct pcmcia_socket;  struct pccard_operations {  	int (*init)(struct pcmcia_socket *sock);  	int (*suspend)(struct pcmcia_socket *sock); -	int (*register_callback)(struct pcmcia_socket *sock, void (*handler)(void *, unsigned int), void * info);  	int (*get_status)(struct pcmcia_socket *sock, u_int *value); -	int (*get_socket)(struct pcmcia_socket *sock, socket_state_t *state);  	int (*set_socket)(struct pcmcia_socket *sock, socket_state_t *state);  	int (*set_io_map)(struct pcmcia_socket *sock, struct pccard_io_map *io);  	int (*set_mem_map)(struct pcmcia_socket *sock, struct pccard_mem_map *mem);  };  struct pccard_resource_ops { -	void	(*validate_mem)		(struct pcmcia_socket *s); +	int	(*validate_mem)		(struct pcmcia_socket *s);  	int	(*adjust_io_region)	(struct resource *res,  					 unsigned long r_start,  					 unsigned long r_end, diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.c b/sound/pcmcia/pdaudiocf/pdaudiocf.c index a7cd2d4df757..77caf43a3109 100644 --- a/sound/pcmcia/pdaudiocf/pdaudiocf.c +++ b/sound/pcmcia/pdaudiocf/pdaudiocf.c @@ -52,16 +52,13 @@ MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard.");  /*   */ -static dev_info_t dev_info = "snd-pdaudiocf";  static struct snd_card *card_list[SNDRV_CARDS]; -static dev_link_t *dev_list;  /*   * prototypes   */  static void pdacf_config(dev_link_t *link); -static int pdacf_event(event_t event, int priority, event_callback_args_t *args); -static void snd_pdacf_detach(dev_link_t *link); +static void snd_pdacf_detach(struct pcmcia_device *p_dev);  static void pdacf_release(dev_link_t *link)  { @@ -83,10 +80,6 @@ static int snd_pdacf_free(struct snd_pdacf *pdacf)  	pdacf_release(link); -	/* Break the link with Card Services */ -	if (link->handle) -		pcmcia_deregister_client(link->handle); -  	card_list[pdacf->index] = NULL;  	pdacf->card = NULL; @@ -103,11 +96,10 @@ static int snd_pdacf_dev_free(struct snd_device *device)  /*   * snd_pdacf_attach - attach callback for cs   */ -static dev_link_t *snd_pdacf_attach(void) +static int snd_pdacf_attach(struct pcmcia_device *p_dev)  { -	client_reg_t client_reg;	/* Register with cardmgr */ -	dev_link_t *link;		/* Info for cardmgr */ -	int i, ret; +	int i; +	dev_link_t *link;               /* Info for cardmgr */  	struct snd_pdacf *pdacf;  	struct snd_card *card;  	static struct snd_device_ops ops = { @@ -122,26 +114,26 @@ static dev_link_t *snd_pdacf_attach(void)  	}  	if (i >= SNDRV_CARDS) {  		snd_printk(KERN_ERR "pdacf: too many cards found\n"); -		return NULL; +		return -EINVAL;  	}  	if (! enable[i]) -		return NULL; /* disabled explicitly */ +		return -ENODEV; /* disabled explicitly */  	/* ok, create a card instance */  	card = snd_card_new(index[i], id[i], THIS_MODULE, 0);  	if (card == NULL) {  		snd_printk(KERN_ERR "pdacf: cannot create a card instance\n"); -		return NULL; +		return -ENOMEM;  	}  	pdacf = snd_pdacf_create(card);  	if (! pdacf) -		return NULL; +		return -EIO;  	if (snd_device_new(card, SNDRV_DEV_LOWLEVEL, pdacf, &ops) < 0) {  		kfree(pdacf);  		snd_card_free(card); -		return NULL; +		return -ENODEV;  	}  	pdacf->index = i; @@ -165,22 +157,12 @@ static dev_link_t *snd_pdacf_attach(void)  	link->conf.Present = PRESENT_OPTION;  	/* Chain drivers */ -	link->next = dev_list; -	dev_list = link; - -	/* Register with Card Services */ -	client_reg.dev_info = &dev_info; -	client_reg.Version = 0x0210; -	client_reg.event_callback_args.client_data = link; - -	ret = pcmcia_register_client(&link->handle, &client_reg); -	if (ret != CS_SUCCESS) { -		cs_error(link->handle, RegisterClient, ret); -		snd_pdacf_detach(link); -		return NULL; -	} +	link->next = NULL; -	return link; +	link->handle = p_dev; +	pdacf_config(link); + +	return 0;  } @@ -227,21 +209,13 @@ static int snd_pdacf_assign_resources(struct snd_pdacf *pdacf, int port, int irq  /*   * snd_pdacf_detach - detach callback for cs   */ -static void snd_pdacf_detach(dev_link_t *link) +static void snd_pdacf_detach(struct pcmcia_device *p_dev)  { +	dev_link_t *link = dev_to_instance(p_dev);  	struct snd_pdacf *chip = link->priv;  	snd_printdd(KERN_DEBUG "pdacf_detach called\n"); -	/* Remove the interface data from the linked list */ -	{ -		dev_link_t **linkp; -		/* Locate device structure */ -		for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) -			if (*linkp == link) -				break; -		if (*linkp) -			*linkp = link->next; -	} +  	if (chip->chip_status & PDAUDIOCF_STAT_IS_CONFIGURED)  		snd_pdacf_powerdown(chip);  	chip->chip_status |= PDAUDIOCF_STAT_IS_STALE; /* to be sure */ @@ -310,62 +284,51 @@ failed:  	pcmcia_release_irq(link->handle, &link->irq);  } -/* - * event callback - */ -static int pdacf_event(event_t event, int priority, event_callback_args_t *args) +#ifdef CONFIG_PM + +static int pdacf_suspend(struct pcmcia_device *dev)  { -	dev_link_t *link = args->client_data; +	dev_link_t *link = dev_to_instance(dev);  	struct snd_pdacf *chip = link->priv; -	switch (event) { -	case CS_EVENT_CARD_REMOVAL: -		snd_printdd(KERN_DEBUG "CARD_REMOVAL..\n"); -		link->state &= ~DEV_PRESENT; -		if (link->state & DEV_CONFIG) { -			chip->chip_status |= PDAUDIOCF_STAT_IS_STALE; -		} -		break; -	case CS_EVENT_CARD_INSERTION: -		snd_printdd(KERN_DEBUG "CARD_INSERTION..\n"); -		link->state |= DEV_PRESENT; -		pdacf_config(link); -		break; -#ifdef CONFIG_PM -	case CS_EVENT_PM_SUSPEND: -		snd_printdd(KERN_DEBUG "SUSPEND\n"); -		link->state |= DEV_SUSPEND; +	snd_printdd(KERN_DEBUG "SUSPEND\n"); +	link->state |= DEV_SUSPEND; +	if (chip) { +		snd_printdd(KERN_DEBUG "snd_pdacf_suspend calling\n"); +		snd_pdacf_suspend(chip, PMSG_SUSPEND); +	} + +	snd_printdd(KERN_DEBUG "RESET_PHYSICAL\n"); +	if (link->state & DEV_CONFIG) +		pcmcia_release_configuration(link->handle); + +	return 0; +} + +static int pdacf_resume(struct pcmcia_device *dev) +{ +	dev_link_t *link = dev_to_instance(dev); +	struct snd_pdacf *chip = link->priv; + +	snd_printdd(KERN_DEBUG "RESUME\n"); +	link->state &= ~DEV_SUSPEND; + +	snd_printdd(KERN_DEBUG "CARD_RESET\n"); +	if (DEV_OK(link)) { +		snd_printdd(KERN_DEBUG "requestconfig...\n"); +		pcmcia_request_configuration(link->handle, &link->conf);  		if (chip) { -			snd_printdd(KERN_DEBUG "snd_pdacf_suspend calling\n"); -			snd_pdacf_suspend(chip, PMSG_SUSPEND); -		} -		/* Fall through... */ -	case CS_EVENT_RESET_PHYSICAL: -		snd_printdd(KERN_DEBUG "RESET_PHYSICAL\n"); -		if (link->state & DEV_CONFIG) -			pcmcia_release_configuration(link->handle); -		break; -	case CS_EVENT_PM_RESUME: -		snd_printdd(KERN_DEBUG "RESUME\n"); -		link->state &= ~DEV_SUSPEND; -		/* Fall through... */ -	case CS_EVENT_CARD_RESET: -		snd_printdd(KERN_DEBUG "CARD_RESET\n"); -		if (DEV_OK(link)) { -			snd_printdd(KERN_DEBUG "requestconfig...\n"); -			pcmcia_request_configuration(link->handle, &link->conf); -			if (chip) { -				snd_printdd(KERN_DEBUG "calling snd_pdacf_resume\n"); -				snd_pdacf_resume(chip); -			} +			snd_printdd(KERN_DEBUG "calling snd_pdacf_resume\n"); +			snd_pdacf_resume(chip);  		} -		snd_printdd(KERN_DEBUG "resume done!\n"); -		break; -#endif  	} +	snd_printdd(KERN_DEBUG "resume done!\n"); +  	return 0;  } +#endif +  /*   * Module entry points   */ @@ -380,10 +343,14 @@ static struct pcmcia_driver pdacf_cs_driver = {  	.drv		= {  		.name	= "snd-pdaudiocf",  	}, -	.attach		= snd_pdacf_attach, -	.event		= pdacf_event, -	.detach		= snd_pdacf_detach, +	.probe		= snd_pdacf_attach, +	.remove		= snd_pdacf_detach,  	.id_table	= snd_pdacf_ids, +#ifdef CONFIG_PM +	.suspend	= pdacf_suspend, +	.resume		= pdacf_resume, +#endif +  };  static int __init init_pdacf(void) @@ -394,7 +361,6 @@ static int __init init_pdacf(void)  static void __exit exit_pdacf(void)  {  	pcmcia_unregister_driver(&pdacf_cs_driver); -	BUG_ON(dev_list != NULL);  }  module_init(init_pdacf); diff --git a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c index 5bb079d17959..66900d20a42f 100644 --- a/sound/pcmcia/vx/vxpocket.c +++ b/sound/pcmcia/vx/vxpocket.c @@ -55,11 +55,6 @@ MODULE_PARM_DESC(ibl, "Capture IBL size for VXPocket soundcard.");   */  static unsigned int card_alloc; -static dev_link_t *dev_list;		/* Linked list of devices */ -static dev_info_t dev_info = "snd-vxpocket"; - - -static int vxpocket_event(event_t event, int priority, event_callback_args_t *args);  /* @@ -73,11 +68,6 @@ static void vxpocket_release(dev_link_t *link)  		pcmcia_release_irq(link->handle, &link->irq);  		link->state &= ~DEV_CONFIG;  	} -	if (link->handle) { -		/* Break the link with Card Services */ -		pcmcia_deregister_client(link->handle); -		link->handle = NULL; -	}  }  /* @@ -144,11 +134,9 @@ static struct snd_vx_hardware vxp440_hw = {   */  static struct snd_vxpocket *snd_vxpocket_new(struct snd_card *card, int ibl)  { -	client_reg_t client_reg;	/* Register with cardmgr */  	dev_link_t *link;		/* Info for cardmgr */  	struct vx_core *chip;  	struct snd_vxpocket *vxp; -	int ret;  	static struct snd_device_ops ops = {  		.dev_free =	snd_vxpocket_dev_free,  	}; @@ -184,26 +172,6 @@ static struct snd_vxpocket *snd_vxpocket_new(struct snd_card *card, int ibl)  	link->conf.ConfigIndex = 1;  	link->conf.Present = PRESENT_OPTION; -	/* Register with Card Services */ -	memset(&client_reg, 0, sizeof(client_reg)); -	client_reg.dev_info = &dev_info; -	client_reg.EventMask =  -		CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL -#ifdef CONFIG_PM -		| CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET -		| CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME -#endif -		; -	client_reg.event_handler = &vxpocket_event; -	client_reg.Version = 0x0210; -	client_reg.event_callback_args.client_data = link; - -	ret = pcmcia_register_client(&link->handle, &client_reg); -	if (ret != CS_SUCCESS) { -		cs_error(link->handle, RegisterClient, ret); -		return NULL; -	} -  	return vxp;  } @@ -317,67 +285,55 @@ failed:  	kfree(parse);  } +#ifdef CONFIG_PM -/* - * event callback - */ -static int vxpocket_event(event_t event, int priority, event_callback_args_t *args) +static int vxp_suspend(struct pcmcia_device *dev)  { -	dev_link_t *link = args->client_data; +	dev_link_t *link = dev_to_instance(dev);  	struct vx_core *chip = link->priv; -	switch (event) { -	case CS_EVENT_CARD_REMOVAL: -		snd_printdd(KERN_DEBUG "CARD_REMOVAL..\n"); -		link->state &= ~DEV_PRESENT; -		if (link->state & DEV_CONFIG) -			chip->chip_status |= VX_STAT_IS_STALE; -		break; -	case CS_EVENT_CARD_INSERTION: -		snd_printdd(KERN_DEBUG "CARD_INSERTION..\n"); -		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; -		vxpocket_config(link); -		break; -#ifdef CONFIG_PM -	case CS_EVENT_PM_SUSPEND: -		snd_printdd(KERN_DEBUG "SUSPEND\n"); -		link->state |= DEV_SUSPEND; +	snd_printdd(KERN_DEBUG "SUSPEND\n"); +	link->state |= DEV_SUSPEND; +	if (chip) { +		snd_printdd(KERN_DEBUG "snd_vx_suspend calling\n"); +		snd_vx_suspend(chip, PMSG_SUSPEND); +	} +	snd_printdd(KERN_DEBUG "RESET_PHYSICAL\n"); +	if (link->state & DEV_CONFIG) +		pcmcia_release_configuration(link->handle); + +	return 0; +} + +static int vxp_resume(struct pcmcia_device *dev) +{ +	dev_link_t *link = dev_to_instance(dev); +	struct vx_core *chip = link->priv; + +	snd_printdd(KERN_DEBUG "RESUME\n"); +	link->state &= ~DEV_SUSPEND; + +	snd_printdd(KERN_DEBUG "CARD_RESET\n"); +	if (DEV_OK(link)) { +		//struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip; +		snd_printdd(KERN_DEBUG "requestconfig...\n"); +		pcmcia_request_configuration(link->handle, &link->conf);  		if (chip) { -			snd_printdd(KERN_DEBUG "snd_vx_suspend calling\n"); -			snd_vx_suspend(chip, PMSG_SUSPEND); +			snd_printdd(KERN_DEBUG "calling snd_vx_resume\n"); +			snd_vx_resume(chip);  		} -		/* Fall through... */ -	case CS_EVENT_RESET_PHYSICAL: -		snd_printdd(KERN_DEBUG "RESET_PHYSICAL\n"); -		if (link->state & DEV_CONFIG) -			pcmcia_release_configuration(link->handle); -		break; -	case CS_EVENT_PM_RESUME: -		snd_printdd(KERN_DEBUG "RESUME\n"); -		link->state &= ~DEV_SUSPEND; -		/* Fall through... */ -	case CS_EVENT_CARD_RESET: -		snd_printdd(KERN_DEBUG "CARD_RESET\n"); -		if (DEV_OK(link)) { -			//struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip; -			snd_printdd(KERN_DEBUG "requestconfig...\n"); -			pcmcia_request_configuration(link->handle, &link->conf); -			if (chip) { -				snd_printdd(KERN_DEBUG "calling snd_vx_resume\n"); -				snd_vx_resume(chip); -			} -		} -		snd_printdd(KERN_DEBUG "resume done!\n"); -		break; -#endif  	} +	snd_printdd(KERN_DEBUG "resume done!\n"); +  	return 0;  } +#endif +  /*   */ -static dev_link_t *vxpocket_attach(void) +static int vxpocket_attach(struct pcmcia_device *p_dev)  {  	struct snd_card *card;  	struct snd_vxpocket *vxp; @@ -390,22 +346,22 @@ static dev_link_t *vxpocket_attach(void)  	}  	if (i >= SNDRV_CARDS) {  		snd_printk(KERN_ERR "vxpocket: too many cards found\n"); -		return NULL; +		return -EINVAL;  	}  	if (! enable[i]) -		return NULL; /* disabled explicitly */ +		return -ENODEV; /* disabled explicitly */  	/* ok, create a card instance */  	card = snd_card_new(index[i], id[i], THIS_MODULE, 0);  	if (card == NULL) {  		snd_printk(KERN_ERR "vxpocket: cannot create a card instance\n"); -		return NULL; +		return -ENOMEM;  	}  	vxp = snd_vxpocket_new(card, ibl[i]);  	if (! vxp) {  		snd_card_free(card); -		return NULL; +		return -ENODEV;  	}  	card->private_data = vxp; @@ -413,17 +369,21 @@ static dev_link_t *vxpocket_attach(void)  	card_alloc |= 1 << i;  	/* Chain drivers */ -	vxp->link.next = dev_list; -	dev_list = &vxp->link; +	vxp->link.next = NULL; + +	vxp->link.handle = p_dev; +	vxp->link.state |= DEV_PRESENT | DEV_CONFIG_PENDING; +	p_dev->instance = &vxp->link; +	vxpocket_config(&vxp->link); -	return &vxp->link; +	return 0;  } -static void vxpocket_detach(dev_link_t *link) +static void vxpocket_detach(struct pcmcia_device *p_dev)  { +	dev_link_t *link = dev_to_instance(p_dev);  	struct snd_vxpocket *vxp;  	struct vx_core *chip; -	dev_link_t **linkp;  	if (! link)  		return; @@ -432,13 +392,6 @@ static void vxpocket_detach(dev_link_t *link)  	chip = (struct vx_core *)vxp;  	card_alloc &= ~(1 << vxp->index); -	/* Remove the interface data from the linked list */ -	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) -		if (*linkp == link) { -			*linkp = link->next; -			break; -		} -  	chip->chip_status |= VX_STAT_IS_STALE; /* to be sure */  	snd_card_disconnect(chip->card);  	vxpocket_release(link); @@ -460,10 +413,13 @@ static struct pcmcia_driver vxp_cs_driver = {  	.drv		= {  		.name	= "snd-vxpocket",  	}, -	.attach		= vxpocket_attach, -	.detach		= vxpocket_detach, -	.event		= vxpocket_event, +	.probe		= vxpocket_attach, +	.remove		= vxpocket_detach,  	.id_table	= vxp_ids, +#ifdef CONFIG_PM +	.suspend	= vxp_suspend, +	.resume		= vxp_resume, +#endif  };  static int __init init_vxpocket(void) @@ -474,7 +430,6 @@ static int __init init_vxpocket(void)  static void __exit exit_vxpocket(void)  {  	pcmcia_unregister_driver(&vxp_cs_driver); -	BUG_ON(dev_list != NULL);  }  module_init(init_vxpocket); | 
