CSX_EVENT_HANDLER(9E) | Driver Entry Points | CSX_EVENT_HANDLER(9E) |
csx_event_handler - PC Card driver event handler
#include <sys/pccard.h> int32_t prefixevent_handler(event_t event, int32_t priority,
event_callback_args_t *args);
illumos architecture specific (illumos DDI)
event
priority
args
Each instance of a PC Card driver must register an event handler to manage events associated with its PC Card. The driver event handler is registered using the event_handler field of the client_req_t structure passed to csx_RegisterClient(9F). The driver may also supply a parameter to be passed to its event handler function using the event_callback_args.client_data field. Typically, this argument is the driver instance's soft state pointer. The driver also registers which events it is interested in receiving through the EventMask field of the client_req_t structure.
Each event is delivered to the driver with a priority, priority. High priority events with CS_EVENT_PRI_HIGH set in priority are delivered above lock level, and the driver must use its high-level event mutex initialized with the iblk_cookie returned by csx_RegisterClient(9F) to protect such events. Low priority events with CS_EVENT_PRI_LOW set in priority are delivered below lock level, and the driver must use its low-level event mutex initialized with a NULL interrupt cookie to protect these events.
csx_RegisterClient(9F) registers the driver's event handler, but no events begin to be delivered to the driver until after a successful call to csx_RequestSocketMask(9F).
In all cases, Card Services delivers an event to each driver instance associated with a function on a multiple function PC Card.
The events and their indications are listed below; they are always delivered as low priority unless otherwise noted:
CS_EVENT_REGISTRATION_COMPLETE
CS_EVENT_CARD_INSERTION
CS_EVENT_CARD_READY
CS_EVENT_CARD_REMOVAL
CS_EVENT_BATTERY_LOW
CS_EVENT_BATTERY_DEAD
CS_EVENT_PM_RESUME
CS_EVENT_PM_SUSPEND
CS_EVENT_CARD_LOCK
CS_EVENT_CARD_UNLOCK
CS_EVENT_EJECTION_REQUEST
CS_EVENT_EJECTION_COMPLETE
CS_EVENT_ERASE_COMPLETE
CS_EVENT_INSERTION_REQUEST
CS_EVENT_INSERTION_COMPLETE
CS_EVENT_CARD_RESET
CS_EVENT_RESET_REQUEST
CS_EVENT_RESET_COMPLETE
CS_EVENT_RESET_PHYSICAL
CS_EVENT_CLIENT_INFO
args->client_data.Attributes
args->client_data.Revision
args->client_data.CSLevel
args->client_data.RevDate
args->client_data.ClientName
args->client_data.VendorName
args->client_data.DriverName
CS_EVENT_WRITE_PROTECT
CS_EVENT_WRITE_PROTECT_WPOFF
CS_EVENT_WRITE_PROTECT_WPON
The structure members of event_callback_args_t are:
void *info; /* event-specific information */ void *client_data; /* driver-private data */ client_info_t client_info; /* client information*/
The structure members of client_info_t are:
unit32_t Attributes; /* attributes */ unit32_t Revisions; /* version number */ uint32_t CSLevel; /* Card Services version */ uint32_t RevDate; /* revision date */ char ClientName[CS_CLIENT_INFO_MAX_NAME_LEN];
/*PC Card driver description */ char VendorName[CS_CLIENT_INFO_MAX_NAME_LEN];
/*PC Card driver vendor name */ char DriverName[MODMAXNAMELEN];
/* PC Card driver name */
CS_SUCCESS
CS_UNSUPPORTED_EVENT
CS_FAILURE
This function is called from high-level interrupt context in the case of high priority events, and from kernel context in the case of low priority events.
static int xx_event(event_t event, int priority, event_callback_args_t *args) {
int rval;
struct xxx *xxx = args->client_data;
client_info_t *info = &args->client_info;
switch (event) {
case CS_EVENT_REGISTRATION_COMPLETE:
ASSERT(priority & CS_EVENT_PRI_LOW);
mutex_enter(&xxx->event_mutex);
xxx->card_state |= XX_REGISTRATION_COMPLETE;
mutex_exit(&xxx->event_mutex);
rval = CS_SUCCESS;
break;
case CS_EVENT_CARD_READY:
ASSERT(priority & CS_EVENT_PRI_LOW);
rval = xx_card_ready(xxx);
mutex_exit(&xxx->event_mutex);
break;
case CS_EVENT_CARD_INSERTION:
ASSERT(priority & CS_EVENT_PRI_LOW);
mutex_enter(&xxx->event_mutex);
rval = xx_card_insertion(xxx);
mutex_exit(&xxx->event_mutex);
break;
case CS_EVENT_CARD_REMOVAL:
if (priority & CS_EVENT_PRI_HIGH) {
mutex_enter(&xxx->hi_event_mutex);
xxx->card_state &= ~XX_CARD_PRESENT;
mutex_exit(&xxx->hi_event_mutex);
} else {
mutex_enter(&xxx->event_mutex);
rval = xx_card_removal(xxx);
mutex_exit(&xxx->event_mutex);
}
break;
case CS_EVENT_CLIENT_INFO:
ASSERT(priority & CS_EVENT_PRI_LOW);
if (GET_CLIENT_INFO_SUBSVC_CS(info->Attributes) ==
CS_CLIENT_INFO_SUBSVC_CS) {
info->Attributes |= CS_CLIENT_INFO_VALID;
info->Revision = 4;
info->CSLevel = CS_VERSION;
info->RevDate = CS_CLIENT_INFO_MAKE_DATE(4, 7, 17);
(void)strncpy(info->ClientName,
"WhizBang Ultra Zowie PC card driver",
CS_CLIENT_INFO_MAX_NAME_LEN)
"ACME PC card drivers, Inc.",
CS_CLIENT_INFO_MAX_NAME_LEN);
rval = CS_SUCCESS;
} else {
rval = CS_UNSUPPORTED_EVENT;
}
break;
case CS_EVENT_WRITE_PROTECT:
ASSERT(priority & CS_EVENT_PRI_LOW);
mutex_enter(&xxx->event_mutex);
if (args->info == CS_EVENT_WRITE_PROTECT_WPOFF) {
xxx->card_state &= ~XX_WRITE_PROTECTED;
} else {
xxx->card_state |= XX_WRITE_PROTECTED;
}
mutex_exit(&xxx->event_mutex);
rval = CS_SUCCESS;
break;
default:
rval = CS_UNSUPPORTED_EVENT;
break;
}
return (rval); }
csx_Event2Text(9F), csx_RegisterClient(9F), csx_RequestSocketMask(9F)
PC Card 95 Standard, PCMCIA/JEIDA
November 22, 1996 | OmniOS |