diff options
Diffstat (limited to 'drivers/pcmcia/pcmcia_ioctl.c')
-rw-r--r-- | drivers/pcmcia/pcmcia_ioctl.c | 120 |
1 files changed, 94 insertions, 26 deletions
diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c index 419f97fc9a62..1703b20cad5d 100644 --- a/drivers/pcmcia/pcmcia_ioctl.c +++ b/drivers/pcmcia/pcmcia_ioctl.c | |||
@@ -38,7 +38,6 @@ | |||
38 | #include <pcmcia/ss.h> | 38 | #include <pcmcia/ss.h> |
39 | 39 | ||
40 | #include "cs_internal.h" | 40 | #include "cs_internal.h" |
41 | #include "ds_internal.h" | ||
42 | 41 | ||
43 | static int major_dev = -1; | 42 | static int major_dev = -1; |
44 | 43 | ||
@@ -58,7 +57,7 @@ typedef struct user_info_t { | |||
58 | } user_info_t; | 57 | } user_info_t; |
59 | 58 | ||
60 | 59 | ||
61 | #ifdef DEBUG | 60 | #ifdef CONFIG_PCMCIA_DEBUG |
62 | extern int ds_pc_debug; | 61 | extern int ds_pc_debug; |
63 | 62 | ||
64 | #define ds_dbg(lvl, fmt, arg...) do { \ | 63 | #define ds_dbg(lvl, fmt, arg...) do { \ |
@@ -149,7 +148,7 @@ static int adjust_irq(struct pcmcia_socket *s, adjust_t *adj) | |||
149 | 148 | ||
150 | irq = adj->resource.irq.IRQ; | 149 | irq = adj->resource.irq.IRQ; |
151 | if ((irq < 0) || (irq > 15)) | 150 | if ((irq < 0) || (irq > 15)) |
152 | return CS_BAD_IRQ; | 151 | return -EINVAL; |
153 | 152 | ||
154 | if (adj->Action != REMOVE_MANAGED_RESOURCE) | 153 | if (adj->Action != REMOVE_MANAGED_RESOURCE) |
155 | return 0; | 154 | return 0; |
@@ -167,7 +166,7 @@ static int adjust_irq(struct pcmcia_socket *s, adjust_t *adj) | |||
167 | #else | 166 | #else |
168 | 167 | ||
169 | static inline int adjust_irq(struct pcmcia_socket *s, adjust_t *adj) { | 168 | static inline int adjust_irq(struct pcmcia_socket *s, adjust_t *adj) { |
170 | return CS_SUCCESS; | 169 | return 0; |
171 | } | 170 | } |
172 | 171 | ||
173 | #endif | 172 | #endif |
@@ -175,7 +174,7 @@ static inline int adjust_irq(struct pcmcia_socket *s, adjust_t *adj) { | |||
175 | static int pcmcia_adjust_resource_info(adjust_t *adj) | 174 | static int pcmcia_adjust_resource_info(adjust_t *adj) |
176 | { | 175 | { |
177 | struct pcmcia_socket *s; | 176 | struct pcmcia_socket *s; |
178 | int ret = CS_UNSUPPORTED_FUNCTION; | 177 | int ret = -ENOSYS; |
179 | unsigned long flags; | 178 | unsigned long flags; |
180 | 179 | ||
181 | down_read(&pcmcia_socket_list_rwsem); | 180 | down_read(&pcmcia_socket_list_rwsem); |
@@ -248,7 +247,7 @@ static int pccard_get_status(struct pcmcia_socket *s, | |||
248 | if (s->state & SOCKET_SUSPEND) | 247 | if (s->state & SOCKET_SUSPEND) |
249 | status->CardState |= CS_EVENT_PM_SUSPEND; | 248 | status->CardState |= CS_EVENT_PM_SUSPEND; |
250 | if (!(s->state & SOCKET_PRESENT)) | 249 | if (!(s->state & SOCKET_PRESENT)) |
251 | return CS_NO_CARD; | 250 | return -ENODEV; |
252 | 251 | ||
253 | c = (p_dev) ? p_dev->function_config : NULL; | 252 | c = (p_dev) ? p_dev->function_config : NULL; |
254 | 253 | ||
@@ -274,7 +273,7 @@ static int pccard_get_status(struct pcmcia_socket *s, | |||
274 | status->CardState |= | 273 | status->CardState |= |
275 | (reg & ESR_REQ_ATTN) ? CS_EVENT_REQUEST_ATTENTION : 0; | 274 | (reg & ESR_REQ_ATTN) ? CS_EVENT_REQUEST_ATTENTION : 0; |
276 | } | 275 | } |
277 | return CS_SUCCESS; | 276 | return 0; |
278 | } | 277 | } |
279 | status->CardState |= | 278 | status->CardState |= |
280 | (val & SS_WRPROT) ? CS_EVENT_WRITE_PROTECT : 0; | 279 | (val & SS_WRPROT) ? CS_EVENT_WRITE_PROTECT : 0; |
@@ -284,9 +283,81 @@ static int pccard_get_status(struct pcmcia_socket *s, | |||
284 | (val & SS_BATWARN) ? CS_EVENT_BATTERY_LOW : 0; | 283 | (val & SS_BATWARN) ? CS_EVENT_BATTERY_LOW : 0; |
285 | status->CardState |= | 284 | status->CardState |= |
286 | (val & SS_READY) ? CS_EVENT_READY_CHANGE : 0; | 285 | (val & SS_READY) ? CS_EVENT_READY_CHANGE : 0; |
287 | return CS_SUCCESS; | 286 | return 0; |
288 | } /* pccard_get_status */ | 287 | } /* pccard_get_status */ |
289 | 288 | ||
289 | int pccard_get_configuration_info(struct pcmcia_socket *s, | ||
290 | struct pcmcia_device *p_dev, | ||
291 | config_info_t *config) | ||
292 | { | ||
293 | config_t *c; | ||
294 | |||
295 | if (!(s->state & SOCKET_PRESENT)) | ||
296 | return -ENODEV; | ||
297 | |||
298 | |||
299 | #ifdef CONFIG_CARDBUS | ||
300 | if (s->state & SOCKET_CARDBUS) { | ||
301 | memset(config, 0, sizeof(config_info_t)); | ||
302 | config->Vcc = s->socket.Vcc; | ||
303 | config->Vpp1 = config->Vpp2 = s->socket.Vpp; | ||
304 | config->Option = s->cb_dev->subordinate->number; | ||
305 | if (s->state & SOCKET_CARDBUS_CONFIG) { | ||
306 | config->Attributes = CONF_VALID_CLIENT; | ||
307 | config->IntType = INT_CARDBUS; | ||
308 | config->AssignedIRQ = s->irq.AssignedIRQ; | ||
309 | if (config->AssignedIRQ) | ||
310 | config->Attributes |= CONF_ENABLE_IRQ; | ||
311 | if (s->io[0].res) { | ||
312 | config->BasePort1 = s->io[0].res->start; | ||
313 | config->NumPorts1 = s->io[0].res->end - | ||
314 | config->BasePort1 + 1; | ||
315 | } | ||
316 | } | ||
317 | return 0; | ||
318 | } | ||
319 | #endif | ||
320 | |||
321 | if (p_dev) { | ||
322 | c = p_dev->function_config; | ||
323 | config->Function = p_dev->func; | ||
324 | } else { | ||
325 | c = NULL; | ||
326 | config->Function = 0; | ||
327 | } | ||
328 | |||
329 | if ((c == NULL) || !(c->state & CONFIG_LOCKED)) { | ||
330 | config->Attributes = 0; | ||
331 | config->Vcc = s->socket.Vcc; | ||
332 | config->Vpp1 = config->Vpp2 = s->socket.Vpp; | ||
333 | return 0; | ||
334 | } | ||
335 | |||
336 | config->Attributes = c->Attributes | CONF_VALID_CLIENT; | ||
337 | config->Vcc = s->socket.Vcc; | ||
338 | config->Vpp1 = config->Vpp2 = s->socket.Vpp; | ||
339 | config->IntType = c->IntType; | ||
340 | config->ConfigBase = c->ConfigBase; | ||
341 | config->Status = c->Status; | ||
342 | config->Pin = c->Pin; | ||
343 | config->Copy = c->Copy; | ||
344 | config->Option = c->Option; | ||
345 | config->ExtStatus = c->ExtStatus; | ||
346 | config->Present = config->CardValues = c->CardValues; | ||
347 | config->IRQAttributes = c->irq.Attributes; | ||
348 | config->AssignedIRQ = s->irq.AssignedIRQ; | ||
349 | config->BasePort1 = c->io.BasePort1; | ||
350 | config->NumPorts1 = c->io.NumPorts1; | ||
351 | config->Attributes1 = c->io.Attributes1; | ||
352 | config->BasePort2 = c->io.BasePort2; | ||
353 | config->NumPorts2 = c->io.NumPorts2; | ||
354 | config->Attributes2 = c->io.Attributes2; | ||
355 | config->IOAddrLines = c->io.IOAddrLines; | ||
356 | |||
357 | return 0; | ||
358 | } /* pccard_get_configuration_info */ | ||
359 | |||
360 | |||
290 | /*====================================================================== | 361 | /*====================================================================== |
291 | 362 | ||
292 | These manage a ring buffer of events pending for one user process | 363 | These manage a ring buffer of events pending for one user process |
@@ -764,7 +835,7 @@ static int ds_ioctl(struct inode * inode, struct file * file, | |||
764 | case DS_GET_CONFIGURATION_INFO: | 835 | case DS_GET_CONFIGURATION_INFO: |
765 | if (buf->config.Function && | 836 | if (buf->config.Function && |
766 | (buf->config.Function >= s->functions)) | 837 | (buf->config.Function >= s->functions)) |
767 | ret = CS_BAD_ARGS; | 838 | ret = -EINVAL; |
768 | else { | 839 | else { |
769 | struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->config.Function); | 840 | struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->config.Function); |
770 | ret = pccard_get_configuration_info(s, p_dev, &buf->config); | 841 | ret = pccard_get_configuration_info(s, p_dev, &buf->config); |
@@ -787,15 +858,15 @@ static int ds_ioctl(struct inode * inode, struct file * file, | |||
787 | break; | 858 | break; |
788 | case DS_PARSE_TUPLE: | 859 | case DS_PARSE_TUPLE: |
789 | buf->tuple.TupleData = buf->tuple_parse.data; | 860 | buf->tuple.TupleData = buf->tuple_parse.data; |
790 | ret = pccard_parse_tuple(&buf->tuple, &buf->tuple_parse.parse); | 861 | ret = pcmcia_parse_tuple(&buf->tuple, &buf->tuple_parse.parse); |
791 | break; | 862 | break; |
792 | case DS_RESET_CARD: | 863 | case DS_RESET_CARD: |
793 | ret = pccard_reset_card(s); | 864 | ret = pcmcia_reset_card(s); |
794 | break; | 865 | break; |
795 | case DS_GET_STATUS: | 866 | case DS_GET_STATUS: |
796 | if (buf->status.Function && | 867 | if (buf->status.Function && |
797 | (buf->status.Function >= s->functions)) | 868 | (buf->status.Function >= s->functions)) |
798 | ret = CS_BAD_ARGS; | 869 | ret = -EINVAL; |
799 | else { | 870 | else { |
800 | struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->status.Function); | 871 | struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->status.Function); |
801 | ret = pccard_get_status(s, p_dev, &buf->status); | 872 | ret = pccard_get_status(s, p_dev, &buf->status); |
@@ -826,7 +897,7 @@ static int ds_ioctl(struct inode * inode, struct file * file, | |||
826 | goto free_out; | 897 | goto free_out; |
827 | } | 898 | } |
828 | 899 | ||
829 | ret = CS_BAD_ARGS; | 900 | ret = -EINVAL; |
830 | 901 | ||
831 | if (!(buf->conf_reg.Function && | 902 | if (!(buf->conf_reg.Function && |
832 | (buf->conf_reg.Function >= s->functions))) { | 903 | (buf->conf_reg.Function >= s->functions))) { |
@@ -867,7 +938,7 @@ static int ds_ioctl(struct inode * inode, struct file * file, | |||
867 | &buf->win_info.map); | 938 | &buf->win_info.map); |
868 | break; | 939 | break; |
869 | case DS_REPLACE_CIS: | 940 | case DS_REPLACE_CIS: |
870 | ret = pcmcia_replace_cis(s, &buf->cisdump); | 941 | ret = pcmcia_replace_cis(s, buf->cisdump.Data, buf->cisdump.Length); |
871 | break; | 942 | break; |
872 | case DS_BIND_REQUEST: | 943 | case DS_BIND_REQUEST: |
873 | if (!capable(CAP_SYS_ADMIN)) { | 944 | if (!capable(CAP_SYS_ADMIN)) { |
@@ -889,22 +960,19 @@ static int ds_ioctl(struct inode * inode, struct file * file, | |||
889 | err = -EINVAL; | 960 | err = -EINVAL; |
890 | } | 961 | } |
891 | 962 | ||
892 | if ((err == 0) && (ret != CS_SUCCESS)) { | 963 | if ((err == 0) && (ret != 0)) { |
893 | ds_dbg(2, "ds_ioctl: ret = %d\n", ret); | 964 | ds_dbg(2, "ds_ioctl: ret = %d\n", ret); |
894 | switch (ret) { | 965 | switch (ret) { |
895 | case CS_BAD_SOCKET: case CS_NO_CARD: | 966 | case -ENODEV: |
896 | err = -ENODEV; break; | 967 | case -EINVAL: |
897 | case CS_BAD_ARGS: case CS_BAD_ATTRIBUTE: case CS_BAD_IRQ: | 968 | case -EBUSY: |
898 | case CS_BAD_TUPLE: | 969 | case -ENOSYS: |
899 | err = -EINVAL; break; | 970 | err = ret; |
900 | case CS_IN_USE: | 971 | break; |
901 | err = -EBUSY; break; | 972 | case -ENOMEM: |
902 | case CS_OUT_OF_RESOURCE: | ||
903 | err = -ENOSPC; break; | 973 | err = -ENOSPC; break; |
904 | case CS_NO_MORE_ITEMS: | 974 | case -ENOSPC: |
905 | err = -ENODATA; break; | 975 | err = -ENODATA; break; |
906 | case CS_UNSUPPORTED_FUNCTION: | ||
907 | err = -ENOSYS; break; | ||
908 | default: | 976 | default: |
909 | err = -EIO; break; | 977 | err = -EIO; break; |
910 | } | 978 | } |