diff options
Diffstat (limited to 'drivers/pcmcia/pcmcia_ioctl.c')
-rw-r--r-- | drivers/pcmcia/pcmcia_ioctl.c | 97 |
1 files changed, 44 insertions, 53 deletions
diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c index b223f5235de7..0bebfdbdc27b 100644 --- a/drivers/pcmcia/pcmcia_ioctl.c +++ b/drivers/pcmcia/pcmcia_ioctl.c | |||
@@ -70,7 +70,7 @@ typedef struct user_info_t { | |||
70 | int event_head, event_tail; | 70 | int event_head, event_tail; |
71 | event_t event[MAX_EVENTS]; | 71 | event_t event[MAX_EVENTS]; |
72 | struct user_info_t *next; | 72 | struct user_info_t *next; |
73 | struct pcmcia_bus_socket *socket; | 73 | struct pcmcia_socket *socket; |
74 | } user_info_t; | 74 | } user_info_t; |
75 | 75 | ||
76 | 76 | ||
@@ -87,15 +87,6 @@ extern int ds_pc_debug; | |||
87 | #endif | 87 | #endif |
88 | 88 | ||
89 | 89 | ||
90 | static struct pcmcia_bus_socket * get_socket_info_by_nr(unsigned int nr) | ||
91 | { | ||
92 | struct pcmcia_socket * s = pcmcia_get_socket_by_nr(nr); | ||
93 | if (s && s->pcmcia) | ||
94 | return s->pcmcia; | ||
95 | else | ||
96 | return NULL; | ||
97 | } | ||
98 | |||
99 | /* backwards-compatible accessing of driver --- by name! */ | 90 | /* backwards-compatible accessing of driver --- by name! */ |
100 | 91 | ||
101 | static struct pcmcia_driver * get_pcmcia_driver (dev_info_t *dev_info) | 92 | static struct pcmcia_driver * get_pcmcia_driver (dev_info_t *dev_info) |
@@ -172,7 +163,7 @@ static void queue_event(user_info_t *user, event_t event) | |||
172 | user->event[user->event_head] = event; | 163 | user->event[user->event_head] = event; |
173 | } | 164 | } |
174 | 165 | ||
175 | void handle_event(struct pcmcia_bus_socket *s, event_t event) | 166 | void handle_event(struct pcmcia_socket *s, event_t event) |
176 | { | 167 | { |
177 | user_info_t *user; | 168 | user_info_t *user; |
178 | for (user = s->user; user; user = user->next) | 169 | for (user = s->user; user; user = user->next) |
@@ -204,18 +195,18 @@ void handle_event(struct pcmcia_bus_socket *s, event_t event) | |||
204 | 195 | ||
205 | ======================================================================*/ | 196 | ======================================================================*/ |
206 | 197 | ||
207 | static int bind_request(struct pcmcia_bus_socket *s, bind_info_t *bind_info) | 198 | static int bind_request(struct pcmcia_socket *s, bind_info_t *bind_info) |
208 | { | 199 | { |
209 | struct pcmcia_driver *p_drv; | 200 | struct pcmcia_driver *p_drv; |
210 | struct pcmcia_device *p_dev; | 201 | struct pcmcia_device *p_dev; |
211 | int ret = 0; | 202 | int ret = 0; |
212 | unsigned long flags; | 203 | unsigned long flags; |
213 | 204 | ||
214 | s = pcmcia_get_bus_socket(s); | 205 | s = pcmcia_get_socket(s); |
215 | if (!s) | 206 | if (!s) |
216 | return -EINVAL; | 207 | return -EINVAL; |
217 | 208 | ||
218 | ds_dbg(2, "bind_request(%d, '%s')\n", s->parent->sock, | 209 | ds_dbg(2, "bind_request(%d, '%s')\n", s->sock, |
219 | (char *)bind_info->dev_info); | 210 | (char *)bind_info->dev_info); |
220 | 211 | ||
221 | p_drv = get_pcmcia_driver(&bind_info->dev_info); | 212 | p_drv = get_pcmcia_driver(&bind_info->dev_info); |
@@ -278,9 +269,9 @@ rescan: | |||
278 | /* | 269 | /* |
279 | * Prevent this racing with a card insertion. | 270 | * Prevent this racing with a card insertion. |
280 | */ | 271 | */ |
281 | down(&s->parent->skt_sem); | 272 | down(&s->skt_sem); |
282 | bus_rescan_devices(&pcmcia_bus_type); | 273 | bus_rescan_devices(&pcmcia_bus_type); |
283 | up(&s->parent->skt_sem); | 274 | up(&s->skt_sem); |
284 | 275 | ||
285 | /* check whether the driver indeed matched. I don't care if this | 276 | /* check whether the driver indeed matched. I don't care if this |
286 | * is racy or not, because it can only happen on cardmgr access | 277 | * is racy or not, because it can only happen on cardmgr access |
@@ -294,7 +285,7 @@ rescan: | |||
294 | err_put_driver: | 285 | err_put_driver: |
295 | put_driver(&p_drv->drv); | 286 | put_driver(&p_drv->drv); |
296 | err_put: | 287 | err_put: |
297 | pcmcia_put_bus_socket(s); | 288 | pcmcia_put_socket(s); |
298 | 289 | ||
299 | return (ret); | 290 | return (ret); |
300 | } /* bind_request */ | 291 | } /* bind_request */ |
@@ -302,7 +293,7 @@ rescan: | |||
302 | 293 | ||
303 | extern struct pci_bus *pcmcia_lookup_bus(struct pcmcia_socket *s); | 294 | extern struct pci_bus *pcmcia_lookup_bus(struct pcmcia_socket *s); |
304 | 295 | ||
305 | static int get_device_info(struct pcmcia_bus_socket *s, bind_info_t *bind_info, int first) | 296 | static int get_device_info(struct pcmcia_socket *s, bind_info_t *bind_info, int first) |
306 | { | 297 | { |
307 | dev_node_t *node; | 298 | dev_node_t *node; |
308 | struct pcmcia_device *p_dev; | 299 | struct pcmcia_device *p_dev; |
@@ -317,7 +308,7 @@ static int get_device_info(struct pcmcia_bus_socket *s, bind_info_t *bind_info, | |||
317 | { | 308 | { |
318 | struct pci_bus *bus; | 309 | struct pci_bus *bus; |
319 | 310 | ||
320 | bus = pcmcia_lookup_bus(s->parent); | 311 | bus = pcmcia_lookup_bus(s); |
321 | if (bus) { | 312 | if (bus) { |
322 | struct list_head *list; | 313 | struct list_head *list; |
323 | struct pci_dev *dev = NULL; | 314 | struct pci_dev *dev = NULL; |
@@ -391,21 +382,21 @@ static int get_device_info(struct pcmcia_bus_socket *s, bind_info_t *bind_info, | |||
391 | static int ds_open(struct inode *inode, struct file *file) | 382 | static int ds_open(struct inode *inode, struct file *file) |
392 | { | 383 | { |
393 | socket_t i = iminor(inode); | 384 | socket_t i = iminor(inode); |
394 | struct pcmcia_bus_socket *s; | 385 | struct pcmcia_socket *s; |
395 | user_info_t *user; | 386 | user_info_t *user; |
396 | 387 | ||
397 | ds_dbg(0, "ds_open(socket %d)\n", i); | 388 | ds_dbg(0, "ds_open(socket %d)\n", i); |
398 | 389 | ||
399 | s = get_socket_info_by_nr(i); | 390 | s = pcmcia_get_socket_by_nr(i); |
400 | if (!s) | 391 | if (!s) |
401 | return -ENODEV; | 392 | return -ENODEV; |
402 | s = pcmcia_get_bus_socket(s); | 393 | s = pcmcia_get_socket(s); |
403 | if (!s) | 394 | if (!s) |
404 | return -ENODEV; | 395 | return -ENODEV; |
405 | 396 | ||
406 | if ((file->f_flags & O_ACCMODE) != O_RDONLY) { | 397 | if ((file->f_flags & O_ACCMODE) != O_RDONLY) { |
407 | if (s->pcmcia_state.busy) { | 398 | if (s->pcmcia_state.busy) { |
408 | pcmcia_put_bus_socket(s); | 399 | pcmcia_put_socket(s); |
409 | return -EBUSY; | 400 | return -EBUSY; |
410 | } | 401 | } |
411 | else | 402 | else |
@@ -414,7 +405,7 @@ static int ds_open(struct inode *inode, struct file *file) | |||
414 | 405 | ||
415 | user = kmalloc(sizeof(user_info_t), GFP_KERNEL); | 406 | user = kmalloc(sizeof(user_info_t), GFP_KERNEL); |
416 | if (!user) { | 407 | if (!user) { |
417 | pcmcia_put_bus_socket(s); | 408 | pcmcia_put_socket(s); |
418 | return -ENOMEM; | 409 | return -ENOMEM; |
419 | } | 410 | } |
420 | user->event_tail = user->event_head = 0; | 411 | user->event_tail = user->event_head = 0; |
@@ -433,7 +424,7 @@ static int ds_open(struct inode *inode, struct file *file) | |||
433 | 424 | ||
434 | static int ds_release(struct inode *inode, struct file *file) | 425 | static int ds_release(struct inode *inode, struct file *file) |
435 | { | 426 | { |
436 | struct pcmcia_bus_socket *s; | 427 | struct pcmcia_socket *s; |
437 | user_info_t *user, **link; | 428 | user_info_t *user, **link; |
438 | 429 | ||
439 | ds_dbg(0, "ds_release(socket %d)\n", iminor(inode)); | 430 | ds_dbg(0, "ds_release(socket %d)\n", iminor(inode)); |
@@ -456,7 +447,7 @@ static int ds_release(struct inode *inode, struct file *file) | |||
456 | *link = user->next; | 447 | *link = user->next; |
457 | user->user_magic = 0; | 448 | user->user_magic = 0; |
458 | kfree(user); | 449 | kfree(user); |
459 | pcmcia_put_bus_socket(s); | 450 | pcmcia_put_socket(s); |
460 | out: | 451 | out: |
461 | return 0; | 452 | return 0; |
462 | } /* ds_release */ | 453 | } /* ds_release */ |
@@ -466,7 +457,7 @@ out: | |||
466 | static ssize_t ds_read(struct file *file, char __user *buf, | 457 | static ssize_t ds_read(struct file *file, char __user *buf, |
467 | size_t count, loff_t *ppos) | 458 | size_t count, loff_t *ppos) |
468 | { | 459 | { |
469 | struct pcmcia_bus_socket *s; | 460 | struct pcmcia_socket *s; |
470 | user_info_t *user; | 461 | user_info_t *user; |
471 | int ret; | 462 | int ret; |
472 | 463 | ||
@@ -510,7 +501,7 @@ static ssize_t ds_write(struct file *file, const char __user *buf, | |||
510 | /* No kernel lock - fine */ | 501 | /* No kernel lock - fine */ |
511 | static u_int ds_poll(struct file *file, poll_table *wait) | 502 | static u_int ds_poll(struct file *file, poll_table *wait) |
512 | { | 503 | { |
513 | struct pcmcia_bus_socket *s; | 504 | struct pcmcia_socket *s; |
514 | user_info_t *user; | 505 | user_info_t *user; |
515 | 506 | ||
516 | ds_dbg(2, "ds_poll(socket %d)\n", iminor(file->f_dentry->d_inode)); | 507 | ds_dbg(2, "ds_poll(socket %d)\n", iminor(file->f_dentry->d_inode)); |
@@ -536,7 +527,7 @@ extern int pcmcia_adjust_resource_info(adjust_t *adj); | |||
536 | static int ds_ioctl(struct inode * inode, struct file * file, | 527 | static int ds_ioctl(struct inode * inode, struct file * file, |
537 | u_int cmd, u_long arg) | 528 | u_int cmd, u_long arg) |
538 | { | 529 | { |
539 | struct pcmcia_bus_socket *s; | 530 | struct pcmcia_socket *s; |
540 | void __user *uarg = (char __user *)arg; | 531 | void __user *uarg = (char __user *)arg; |
541 | u_int size; | 532 | u_int size; |
542 | int ret, err; | 533 | int ret, err; |
@@ -589,57 +580,57 @@ static int ds_ioctl(struct inode * inode, struct file * file, | |||
589 | break; | 580 | break; |
590 | case DS_GET_CONFIGURATION_INFO: | 581 | case DS_GET_CONFIGURATION_INFO: |
591 | if (buf->config.Function && | 582 | if (buf->config.Function && |
592 | (buf->config.Function >= s->parent->functions)) | 583 | (buf->config.Function >= s->functions)) |
593 | ret = CS_BAD_ARGS; | 584 | ret = CS_BAD_ARGS; |
594 | else | 585 | else |
595 | ret = pccard_get_configuration_info(s->parent, | 586 | ret = pccard_get_configuration_info(s, |
596 | buf->config.Function, &buf->config); | 587 | buf->config.Function, &buf->config); |
597 | break; | 588 | break; |
598 | case DS_GET_FIRST_TUPLE: | 589 | case DS_GET_FIRST_TUPLE: |
599 | down(&s->parent->skt_sem); | 590 | down(&s->skt_sem); |
600 | pcmcia_validate_mem(s->parent); | 591 | pcmcia_validate_mem(s); |
601 | up(&s->parent->skt_sem); | 592 | up(&s->skt_sem); |
602 | ret = pccard_get_first_tuple(s->parent, BIND_FN_ALL, &buf->tuple); | 593 | ret = pccard_get_first_tuple(s, BIND_FN_ALL, &buf->tuple); |
603 | break; | 594 | break; |
604 | case DS_GET_NEXT_TUPLE: | 595 | case DS_GET_NEXT_TUPLE: |
605 | ret = pccard_get_next_tuple(s->parent, BIND_FN_ALL, &buf->tuple); | 596 | ret = pccard_get_next_tuple(s, BIND_FN_ALL, &buf->tuple); |
606 | break; | 597 | break; |
607 | case DS_GET_TUPLE_DATA: | 598 | case DS_GET_TUPLE_DATA: |
608 | buf->tuple.TupleData = buf->tuple_parse.data; | 599 | buf->tuple.TupleData = buf->tuple_parse.data; |
609 | buf->tuple.TupleDataMax = sizeof(buf->tuple_parse.data); | 600 | buf->tuple.TupleDataMax = sizeof(buf->tuple_parse.data); |
610 | ret = pccard_get_tuple_data(s->parent, &buf->tuple); | 601 | ret = pccard_get_tuple_data(s, &buf->tuple); |
611 | break; | 602 | break; |
612 | case DS_PARSE_TUPLE: | 603 | case DS_PARSE_TUPLE: |
613 | buf->tuple.TupleData = buf->tuple_parse.data; | 604 | buf->tuple.TupleData = buf->tuple_parse.data; |
614 | ret = pccard_parse_tuple(&buf->tuple, &buf->tuple_parse.parse); | 605 | ret = pccard_parse_tuple(&buf->tuple, &buf->tuple_parse.parse); |
615 | break; | 606 | break; |
616 | case DS_RESET_CARD: | 607 | case DS_RESET_CARD: |
617 | ret = pccard_reset_card(s->parent); | 608 | ret = pccard_reset_card(s); |
618 | break; | 609 | break; |
619 | case DS_GET_STATUS: | 610 | case DS_GET_STATUS: |
620 | if (buf->status.Function && | 611 | if (buf->status.Function && |
621 | (buf->status.Function >= s->parent->functions)) | 612 | (buf->status.Function >= s->functions)) |
622 | ret = CS_BAD_ARGS; | 613 | ret = CS_BAD_ARGS; |
623 | else | 614 | else |
624 | ret = pccard_get_status(s->parent, buf->status.Function, &buf->status); | 615 | ret = pccard_get_status(s, buf->status.Function, &buf->status); |
625 | break; | 616 | break; |
626 | case DS_VALIDATE_CIS: | 617 | case DS_VALIDATE_CIS: |
627 | down(&s->parent->skt_sem); | 618 | down(&s->skt_sem); |
628 | pcmcia_validate_mem(s->parent); | 619 | pcmcia_validate_mem(s); |
629 | up(&s->parent->skt_sem); | 620 | up(&s->skt_sem); |
630 | ret = pccard_validate_cis(s->parent, BIND_FN_ALL, &buf->cisinfo); | 621 | ret = pccard_validate_cis(s, BIND_FN_ALL, &buf->cisinfo); |
631 | break; | 622 | break; |
632 | case DS_SUSPEND_CARD: | 623 | case DS_SUSPEND_CARD: |
633 | ret = pcmcia_suspend_card(s->parent); | 624 | ret = pcmcia_suspend_card(s); |
634 | break; | 625 | break; |
635 | case DS_RESUME_CARD: | 626 | case DS_RESUME_CARD: |
636 | ret = pcmcia_resume_card(s->parent); | 627 | ret = pcmcia_resume_card(s); |
637 | break; | 628 | break; |
638 | case DS_EJECT_CARD: | 629 | case DS_EJECT_CARD: |
639 | err = pcmcia_eject_card(s->parent); | 630 | err = pcmcia_eject_card(s); |
640 | break; | 631 | break; |
641 | case DS_INSERT_CARD: | 632 | case DS_INSERT_CARD: |
642 | err = pcmcia_insert_card(s->parent); | 633 | err = pcmcia_insert_card(s); |
643 | break; | 634 | break; |
644 | case DS_ACCESS_CONFIGURATION_REGISTER: | 635 | case DS_ACCESS_CONFIGURATION_REGISTER: |
645 | if ((buf->conf_reg.Action == CS_WRITE) && !capable(CAP_SYS_ADMIN)) { | 636 | if ((buf->conf_reg.Action == CS_WRITE) && !capable(CAP_SYS_ADMIN)) { |
@@ -647,10 +638,10 @@ static int ds_ioctl(struct inode * inode, struct file * file, | |||
647 | goto free_out; | 638 | goto free_out; |
648 | } | 639 | } |
649 | if (buf->conf_reg.Function && | 640 | if (buf->conf_reg.Function && |
650 | (buf->conf_reg.Function >= s->parent->functions)) | 641 | (buf->conf_reg.Function >= s->functions)) |
651 | ret = CS_BAD_ARGS; | 642 | ret = CS_BAD_ARGS; |
652 | else | 643 | else |
653 | ret = pccard_access_configuration_register(s->parent, | 644 | ret = pccard_access_configuration_register(s, |
654 | buf->conf_reg.Function, &buf->conf_reg); | 645 | buf->conf_reg.Function, &buf->conf_reg); |
655 | break; | 646 | break; |
656 | case DS_GET_FIRST_REGION: | 647 | case DS_GET_FIRST_REGION: |
@@ -671,11 +662,11 @@ static int ds_ioctl(struct inode * inode, struct file * file, | |||
671 | goto free_out; | 662 | goto free_out; |
672 | break; | 663 | break; |
673 | case DS_GET_FIRST_WINDOW: | 664 | case DS_GET_FIRST_WINDOW: |
674 | ret = pcmcia_get_window(s->parent, &buf->win_info.handle, 0, | 665 | ret = pcmcia_get_window(s, &buf->win_info.handle, 0, |
675 | &buf->win_info.window); | 666 | &buf->win_info.window); |
676 | break; | 667 | break; |
677 | case DS_GET_NEXT_WINDOW: | 668 | case DS_GET_NEXT_WINDOW: |
678 | ret = pcmcia_get_window(s->parent, &buf->win_info.handle, | 669 | ret = pcmcia_get_window(s, &buf->win_info.handle, |
679 | buf->win_info.handle->index + 1, &buf->win_info.window); | 670 | buf->win_info.handle->index + 1, &buf->win_info.window); |
680 | break; | 671 | break; |
681 | case DS_GET_MEM_PAGE: | 672 | case DS_GET_MEM_PAGE: |
@@ -683,7 +674,7 @@ static int ds_ioctl(struct inode * inode, struct file * file, | |||
683 | &buf->win_info.map); | 674 | &buf->win_info.map); |
684 | break; | 675 | break; |
685 | case DS_REPLACE_CIS: | 676 | case DS_REPLACE_CIS: |
686 | ret = pcmcia_replace_cis(s->parent, &buf->cisdump); | 677 | ret = pcmcia_replace_cis(s, &buf->cisdump); |
687 | break; | 678 | break; |
688 | case DS_BIND_REQUEST: | 679 | case DS_BIND_REQUEST: |
689 | if (!capable(CAP_SYS_ADMIN)) { | 680 | if (!capable(CAP_SYS_ADMIN)) { |