aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia/pcmcia_ioctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pcmcia/pcmcia_ioctl.c')
-rw-r--r--drivers/pcmcia/pcmcia_ioctl.c120
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
43static int major_dev = -1; 42static 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
62extern int ds_pc_debug; 61extern 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
169static inline int adjust_irq(struct pcmcia_socket *s, adjust_t *adj) { 168static 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) {
175static int pcmcia_adjust_resource_info(adjust_t *adj) 174static 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
289int 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 }