diff options
| -rw-r--r-- | drivers/pcmcia/cistpl.c | 27 | ||||
| -rw-r--r-- | drivers/pcmcia/rsrc_nonstatic.c | 5 |
2 files changed, 26 insertions, 6 deletions
diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c index 17a5da32cce1..602f574898dc 100644 --- a/drivers/pcmcia/cistpl.c +++ b/drivers/pcmcia/cistpl.c | |||
| @@ -83,6 +83,8 @@ void release_cis_mem(struct pcmcia_socket *s) | |||
| 83 | * Map the card memory at "card_offset" into virtual space. | 83 | * Map the card memory at "card_offset" into virtual space. |
| 84 | * If flags & MAP_ATTRIB, map the attribute space, otherwise | 84 | * If flags & MAP_ATTRIB, map the attribute space, otherwise |
| 85 | * map the memory space. | 85 | * map the memory space. |
| 86 | * | ||
| 87 | * Must be called with ops_mutex held. | ||
| 86 | */ | 88 | */ |
| 87 | static void __iomem * | 89 | static void __iomem * |
| 88 | set_cis_map(struct pcmcia_socket *s, unsigned int card_offset, unsigned int flags) | 90 | set_cis_map(struct pcmcia_socket *s, unsigned int card_offset, unsigned int flags) |
| @@ -90,13 +92,11 @@ set_cis_map(struct pcmcia_socket *s, unsigned int card_offset, unsigned int flag | |||
| 90 | pccard_mem_map *mem = &s->cis_mem; | 92 | pccard_mem_map *mem = &s->cis_mem; |
| 91 | int ret; | 93 | int ret; |
| 92 | 94 | ||
| 93 | mutex_lock(&s->ops_mutex); | ||
| 94 | if (!(s->features & SS_CAP_STATIC_MAP) && (mem->res == NULL)) { | 95 | if (!(s->features & SS_CAP_STATIC_MAP) && (mem->res == NULL)) { |
| 95 | mem->res = pcmcia_find_mem_region(0, s->map_size, s->map_size, 0, s); | 96 | mem->res = pcmcia_find_mem_region(0, s->map_size, s->map_size, 0, s); |
| 96 | if (mem->res == NULL) { | 97 | if (mem->res == NULL) { |
| 97 | dev_printk(KERN_NOTICE, &s->dev, | 98 | dev_printk(KERN_NOTICE, &s->dev, |
| 98 | "cs: unable to map card memory!\n"); | 99 | "cs: unable to map card memory!\n"); |
| 99 | mutex_unlock(&s->ops_mutex); | ||
| 100 | return NULL; | 100 | return NULL; |
| 101 | } | 101 | } |
| 102 | s->cis_virt = NULL; | 102 | s->cis_virt = NULL; |
| @@ -112,7 +112,6 @@ set_cis_map(struct pcmcia_socket *s, unsigned int card_offset, unsigned int flag | |||
| 112 | if (ret) { | 112 | if (ret) { |
| 113 | iounmap(s->cis_virt); | 113 | iounmap(s->cis_virt); |
| 114 | s->cis_virt = NULL; | 114 | s->cis_virt = NULL; |
| 115 | mutex_unlock(&s->ops_mutex); | ||
| 116 | return NULL; | 115 | return NULL; |
| 117 | } | 116 | } |
| 118 | 117 | ||
| @@ -122,7 +121,6 @@ set_cis_map(struct pcmcia_socket *s, unsigned int card_offset, unsigned int flag | |||
| 122 | s->cis_virt = ioremap(mem->static_start, s->map_size); | 121 | s->cis_virt = ioremap(mem->static_start, s->map_size); |
| 123 | } | 122 | } |
| 124 | 123 | ||
| 125 | mutex_unlock(&s->ops_mutex); | ||
| 126 | return s->cis_virt; | 124 | return s->cis_virt; |
| 127 | } | 125 | } |
| 128 | 126 | ||
| @@ -145,6 +143,7 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, | |||
| 145 | 143 | ||
| 146 | dev_dbg(&s->dev, "pcmcia_read_cis_mem(%d, %#x, %u)\n", attr, addr, len); | 144 | dev_dbg(&s->dev, "pcmcia_read_cis_mem(%d, %#x, %u)\n", attr, addr, len); |
| 147 | 145 | ||
| 146 | mutex_lock(&s->ops_mutex); | ||
| 148 | if (attr & IS_INDIRECT) { | 147 | if (attr & IS_INDIRECT) { |
| 149 | /* Indirect accesses use a bunch of special registers at fixed | 148 | /* Indirect accesses use a bunch of special registers at fixed |
| 150 | locations in common memory */ | 149 | locations in common memory */ |
| @@ -156,7 +155,9 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, | |||
| 156 | 155 | ||
| 157 | sys = set_cis_map(s, 0, MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0)); | 156 | sys = set_cis_map(s, 0, MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0)); |
| 158 | if (!sys) { | 157 | if (!sys) { |
| 158 | dev_dbg(&s->dev, "could not map memory\n"); | ||
| 159 | memset(ptr, 0xff, len); | 159 | memset(ptr, 0xff, len); |
| 160 | mutex_unlock(&s->ops_mutex); | ||
| 160 | return -1; | 161 | return -1; |
| 161 | } | 162 | } |
| 162 | 163 | ||
| @@ -170,6 +171,9 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, | |||
| 170 | } else { | 171 | } else { |
| 171 | u_int inc = 1, card_offset, flags; | 172 | u_int inc = 1, card_offset, flags; |
| 172 | 173 | ||
| 174 | if (addr > CISTPL_MAX_CIS_SIZE) | ||
| 175 | dev_dbg(&s->dev, "attempt to read CIS mem at addr %#x", addr); | ||
| 176 | |||
| 173 | flags = MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0); | 177 | flags = MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0); |
| 174 | if (attr) { | 178 | if (attr) { |
| 175 | flags |= MAP_ATTRIB; | 179 | flags |= MAP_ATTRIB; |
| @@ -181,7 +185,9 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, | |||
| 181 | while (len) { | 185 | while (len) { |
| 182 | sys = set_cis_map(s, card_offset, flags); | 186 | sys = set_cis_map(s, card_offset, flags); |
| 183 | if (!sys) { | 187 | if (!sys) { |
| 188 | dev_dbg(&s->dev, "could not map memory\n"); | ||
| 184 | memset(ptr, 0xff, len); | 189 | memset(ptr, 0xff, len); |
| 190 | mutex_unlock(&s->ops_mutex); | ||
| 185 | return -1; | 191 | return -1; |
| 186 | } | 192 | } |
| 187 | end = sys + s->map_size; | 193 | end = sys + s->map_size; |
| @@ -195,6 +201,7 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, | |||
| 195 | addr = 0; | 201 | addr = 0; |
| 196 | } | 202 | } |
| 197 | } | 203 | } |
| 204 | mutex_unlock(&s->ops_mutex); | ||
| 198 | dev_dbg(&s->dev, " %#2.2x %#2.2x %#2.2x %#2.2x ...\n", | 205 | dev_dbg(&s->dev, " %#2.2x %#2.2x %#2.2x %#2.2x ...\n", |
| 199 | *(u_char *)(ptr+0), *(u_char *)(ptr+1), | 206 | *(u_char *)(ptr+0), *(u_char *)(ptr+1), |
| 200 | *(u_char *)(ptr+2), *(u_char *)(ptr+3)); | 207 | *(u_char *)(ptr+2), *(u_char *)(ptr+3)); |
| @@ -210,6 +217,7 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, | |||
| 210 | 217 | ||
| 211 | dev_dbg(&s->dev, "pcmcia_write_cis_mem(%d, %#x, %u)\n", attr, addr, len); | 218 | dev_dbg(&s->dev, "pcmcia_write_cis_mem(%d, %#x, %u)\n", attr, addr, len); |
| 212 | 219 | ||
| 220 | mutex_lock(&s->ops_mutex); | ||
| 213 | if (attr & IS_INDIRECT) { | 221 | if (attr & IS_INDIRECT) { |
| 214 | /* Indirect accesses use a bunch of special registers at fixed | 222 | /* Indirect accesses use a bunch of special registers at fixed |
| 215 | locations in common memory */ | 223 | locations in common memory */ |
| @@ -220,8 +228,11 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, | |||
| 220 | } | 228 | } |
| 221 | 229 | ||
| 222 | sys = set_cis_map(s, 0, MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0)); | 230 | sys = set_cis_map(s, 0, MAP_ACTIVE | ((cis_width) ? MAP_16BIT : 0)); |
| 223 | if (!sys) | 231 | if (!sys) { |
| 232 | dev_dbg(&s->dev, "could not map memory\n"); | ||
| 233 | mutex_unlock(&s->ops_mutex); | ||
| 224 | return; /* FIXME: Error */ | 234 | return; /* FIXME: Error */ |
| 235 | } | ||
| 225 | 236 | ||
| 226 | writeb(flags, sys+CISREG_ICTRL0); | 237 | writeb(flags, sys+CISREG_ICTRL0); |
| 227 | writeb(addr & 0xff, sys+CISREG_IADDR0); | 238 | writeb(addr & 0xff, sys+CISREG_IADDR0); |
| @@ -243,8 +254,11 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, | |||
| 243 | card_offset = addr & ~(s->map_size-1); | 254 | card_offset = addr & ~(s->map_size-1); |
| 244 | while (len) { | 255 | while (len) { |
| 245 | sys = set_cis_map(s, card_offset, flags); | 256 | sys = set_cis_map(s, card_offset, flags); |
| 246 | if (!sys) | 257 | if (!sys) { |
| 258 | dev_dbg(&s->dev, "could not map memory\n"); | ||
| 259 | mutex_unlock(&s->ops_mutex); | ||
| 247 | return; /* FIXME: error */ | 260 | return; /* FIXME: error */ |
| 261 | } | ||
| 248 | 262 | ||
| 249 | end = sys + s->map_size; | 263 | end = sys + s->map_size; |
| 250 | sys = sys + (addr & (s->map_size-1)); | 264 | sys = sys + (addr & (s->map_size-1)); |
| @@ -257,6 +271,7 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, | |||
| 257 | addr = 0; | 271 | addr = 0; |
| 258 | } | 272 | } |
| 259 | } | 273 | } |
| 274 | mutex_unlock(&s->ops_mutex); | ||
| 260 | } | 275 | } |
| 261 | 276 | ||
| 262 | 277 | ||
diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c index c13424f7b479..19cecb539759 100644 --- a/drivers/pcmcia/rsrc_nonstatic.c +++ b/drivers/pcmcia/rsrc_nonstatic.c | |||
| @@ -273,6 +273,11 @@ static int readable(struct pcmcia_socket *s, struct resource *res, | |||
| 273 | { | 273 | { |
| 274 | int ret = -EINVAL; | 274 | int ret = -EINVAL; |
| 275 | 275 | ||
| 276 | if (s->fake_cis) { | ||
| 277 | dev_dbg(&s->dev, "fake CIS is being used: can't validate mem\n"); | ||
| 278 | return 0; | ||
| 279 | } | ||
| 280 | |||
| 276 | s->cis_mem.res = res; | 281 | s->cis_mem.res = res; |
| 277 | s->cis_virt = ioremap(res->start, s->map_size); | 282 | s->cis_virt = ioremap(res->start, s->map_size); |
| 278 | if (s->cis_virt) { | 283 | if (s->cis_virt) { |
