If a resource is already in use, mark it with -EBUSY. Same for cards already
asleep.
(includes a fix for a bug found by Larry Finger -- thanks!)
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
static int socket_suspend(struct pcmcia_socket *skt)
{
if (skt->state & SOCKET_SUSPEND)
static int socket_suspend(struct pcmcia_socket *skt)
{
if (skt->state & SOCKET_SUSPEND)
send_event(skt, CS_EVENT_PM_SUSPEND, CS_EVENT_PRI_LOW);
skt->socket = dead_socket;
send_event(skt, CS_EVENT_PM_SUSPEND, CS_EVENT_PRI_LOW);
skt->socket = dead_socket;
int ret;
if (!(skt->state & SOCKET_SUSPEND))
int ret;
if (!(skt->state & SOCKET_SUSPEND))
skt->socket = dead_socket;
skt->ops->init(skt);
skt->socket = dead_socket;
skt->ops->init(skt);
break;
}
if (skt->state & SOCKET_SUSPEND) {
break;
}
if (skt->state & SOCKET_SUSPEND) {
break;
}
if (skt->state & SOCKET_CARDBUS) {
break;
}
if (skt->state & SOCKET_CARDBUS) {
c = p_dev->function_config;
if (c->state & CONFIG_LOCKED)
return -EACCES;
c = p_dev->function_config;
if (c->state & CONFIG_LOCKED)
return -EACCES;
- if (c->state & CONFIG_IO_REQ)
- return CS_IN_USE;
+ if (c->state & CONFIG_IO_REQ) {
+ ds_dbg(s, 0, "IO already configured\n");
+ return -EBUSY;
+ }
if (req->Attributes1 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS))
return CS_BAD_ATTRIBUTE;
if ((req->NumPorts2 > 0) &&
(req->Attributes2 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS)))
return CS_BAD_ATTRIBUTE;
if (req->Attributes1 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS))
return CS_BAD_ATTRIBUTE;
if ((req->NumPorts2 > 0) &&
(req->Attributes2 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS)))
return CS_BAD_ATTRIBUTE;
+ ds_dbg(s, 1, "trying to allocate resource 1\n");
if (alloc_io_space(s, req->Attributes1, &req->BasePort1,
if (alloc_io_space(s, req->Attributes1, &req->BasePort1,
- req->NumPorts1, req->IOAddrLines))
- return CS_IN_USE;
+ req->NumPorts1, req->IOAddrLines)) {
+ ds_dbg(s, 0, "allocation of resource 1 failed\n");
+ return -EBUSY;
+ }
+ ds_dbg(s, 1, "trying to allocate resource 2\n");
if (alloc_io_space(s, req->Attributes2, &req->BasePort2,
req->NumPorts2, req->IOAddrLines)) {
if (alloc_io_space(s, req->Attributes2, &req->BasePort2,
req->NumPorts2, req->IOAddrLines)) {
+ ds_dbg(s, 0, "allocation of resource 2 failed\n");
release_io_space(s, req->BasePort1, req->NumPorts1);
release_io_space(s, req->BasePort1, req->NumPorts1);
{
struct pcmcia_socket *s = p_dev->socket;
config_t *c;
{
struct pcmcia_socket *s = p_dev->socket;
config_t *c;
- int ret = CS_IN_USE, irq = 0;
+ int ret = -EINVAL, irq = 0;
int type;
if (!(s->state & SOCKET_PRESENT))
int type;
if (!(s->state & SOCKET_PRESENT))
c = p_dev->function_config;
if (c->state & CONFIG_LOCKED)
return -EACCES;
c = p_dev->function_config;
if (c->state & CONFIG_LOCKED)
return -EACCES;
- if (c->state & CONFIG_IRQ_REQ)
- return CS_IN_USE;
+ if (c->state & CONFIG_IRQ_REQ) {
+ ds_dbg(s, 0, "IRQ already configured\n");
+ return -EBUSY;
+ }
/* Decide what type of interrupt we are registering */
type = 0;
/* Decide what type of interrupt we are registering */
type = 0;
}
if (ret && (req->Attributes & IRQ_HANDLE_PRESENT)) {
}
if (ret && (req->Attributes & IRQ_HANDLE_PRESENT)) {
- if (request_irq(irq, req->Handler, type, p_dev->devname, req->Instance))
- return CS_IN_USE;
+ ret = request_irq(irq, req->Handler, type,
+ p_dev->devname, req->Instance);
+ if (ret)
+ return ret;
}
/* Make sure the fact the request type was overridden is passed back */
}
/* Make sure the fact the request type was overridden is passed back */
/* Allocate system memory window */
for (w = 0; w < MAX_WIN; w++)
if (!(s->state & SOCKET_WIN_REQ(w))) break;
/* Allocate system memory window */
for (w = 0; w < MAX_WIN; w++)
if (!(s->state & SOCKET_WIN_REQ(w))) break;
- if (w == MAX_WIN)
- return CS_IN_USE;
+ if (w == MAX_WIN) {
+ ds_dbg(s, 0, "all windows are used already\n");
+ return -EINVAL;
+ }
win = &s->win[w];
win->magic = WINDOW_MAGIC;
win = &s->win[w];
win->magic = WINDOW_MAGIC;
if (!(s->features & SS_CAP_STATIC_MAP)) {
win->ctl.res = pcmcia_find_mem_region(req->Base, req->Size, align,
(req->Attributes & WIN_MAP_BELOW_1MB), s);
if (!(s->features & SS_CAP_STATIC_MAP)) {
win->ctl.res = pcmcia_find_mem_region(req->Base, req->Size, align,
(req->Attributes & WIN_MAP_BELOW_1MB), s);
- if (!win->ctl.res)
- return CS_IN_USE;
+ if (!win->ctl.res) {
+ ds_dbg(s, 0, "allocating mem region failed\n");
+ return -EINVAL;
+ }
}
(*p_dev)->_win |= CLIENT_WIN_REQ(w);
}
(*p_dev)->_win |= CLIENT_WIN_REQ(w);
#define CS_BAD_ARG_LENGTH -ENODEV
#define CS_BAD_ARGS 0x1c
#define CS_CONFIGURATION_LOCKED -EACCES
#define CS_BAD_ARG_LENGTH -ENODEV
#define CS_BAD_ARGS 0x1c
#define CS_CONFIGURATION_LOCKED -EACCES
+#define CS_IN_USE -EBUSY
#define CS_NO_MORE_ITEMS 0x1f
#define CS_OUT_OF_RESOURCE -ENOMEM
#define CS_BAD_HANDLE -EINVAL
#define CS_NO_MORE_ITEMS 0x1f
#define CS_OUT_OF_RESOURCE -ENOMEM
#define CS_BAD_HANDLE -EINVAL