| 5682 | } |
| 5683 | |
| 5684 | static int |
| 5685 | devctl2_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag, |
| 5686 | struct thread *td) |
| 5687 | { |
| 5688 | struct devreq *req; |
| 5689 | device_t dev; |
| 5690 | int error, old; |
| 5691 | |
| 5692 | /* Locate the device to control. */ |
| 5693 | mtx_lock(&Giant); |
| 5694 | req = (struct devreq *)data; |
| 5695 | switch (cmd) { |
| 5696 | case DEV_ATTACH: |
| 5697 | case DEV_DETACH: |
| 5698 | case DEV_ENABLE: |
| 5699 | case DEV_DISABLE: |
| 5700 | case DEV_SUSPEND: |
| 5701 | case DEV_RESUME: |
| 5702 | case DEV_SET_DRIVER: |
| 5703 | case DEV_CLEAR_DRIVER: |
| 5704 | case DEV_RESCAN: |
| 5705 | case DEV_DELETE: |
| 5706 | case DEV_RESET: |
| 5707 | error = priv_check(td, PRIV_DRIVER); |
| 5708 | if (error == 0) |
| 5709 | error = find_device(req, &dev); |
| 5710 | break; |
| 5711 | case DEV_FREEZE: |
| 5712 | case DEV_THAW: |
| 5713 | error = priv_check(td, PRIV_DRIVER); |
| 5714 | break; |
| 5715 | default: |
| 5716 | error = ENOTTY; |
| 5717 | break; |
| 5718 | } |
| 5719 | if (error) { |
| 5720 | mtx_unlock(&Giant); |
| 5721 | return (error); |
| 5722 | } |
| 5723 | |
| 5724 | /* Perform the requested operation. */ |
| 5725 | switch (cmd) { |
| 5726 | case DEV_ATTACH: |
| 5727 | if (device_is_attached(dev) && (dev->flags & DF_REBID) == 0) |
| 5728 | error = EBUSY; |
| 5729 | else if (!device_is_enabled(dev)) |
| 5730 | error = ENXIO; |
| 5731 | else |
| 5732 | error = device_probe_and_attach(dev); |
| 5733 | break; |
| 5734 | case DEV_DETACH: |
| 5735 | if (!device_is_attached(dev)) { |
| 5736 | error = ENXIO; |
| 5737 | break; |
| 5738 | } |
| 5739 | if (!(req->dr_flags & DEVF_FORCE_DETACH)) { |
| 5740 | error = device_quiesce(dev); |
| 5741 | if (error) |
nothing calls this directly
no test coverage detected