9296f9626bcb2c5b882b07bfa19e9c44fc659f50
2 * Copyright (C) 2005-2007 Takahiro Hirofuchi
8 struct usbip_vhci_driver
*vhci_driver
;
10 static struct usbip_imported_device
*imported_device_init(struct usbip_imported_device
*idev
, char *busid
)
12 struct sysfs_device
*sudev
;
14 sudev
= sysfs_open_device("usb", busid
);
16 err("sysfs_open_device %s", busid
);
19 read_usb_device(sudev
, &idev
->udev
);
20 sysfs_close_device(sudev
);
22 /* add class devices of this imported device */
23 struct usbip_class_device
*cdev
;
24 dlist_for_each_data(vhci_driver
->cdev_list
, cdev
,
25 struct usbip_class_device
) {
26 if (!strncmp(cdev
->dev_path
, idev
->udev
.path
,
27 strlen(idev
->udev
.path
))) {
28 struct usbip_class_device
*new_cdev
;
30 /* alloc and copy because dlist is linked from only one list */
31 new_cdev
= calloc(1, sizeof(*new_cdev
));
35 memcpy(new_cdev
, cdev
, sizeof(*new_cdev
));
36 dlist_unshift(idev
->cdev_list
, (void*) new_cdev
);
48 static int parse_status(char *value
)
54 for (int i
= 0; i
< vhci_driver
->nports
; i
++)
55 bzero(&vhci_driver
->idev
[i
], sizeof(struct usbip_imported_device
));
58 /* skip a header line */
59 c
= strchr(value
, '\n') + 1;
62 int port
, status
, speed
, devid
;
64 char lbusid
[SYSFS_BUS_ID_SIZE
];
66 ret
= sscanf(c
, "%d %d %d %x %lx %s\n",
67 &port
, &status
, &speed
,
68 &devid
, &socket
, lbusid
);
75 dbg("port %d status %d speed %d devid %x",
76 port
, status
, speed
, devid
);
77 dbg("socket %lx lbusid %s", socket
, lbusid
);
80 /* if a device is connected, look at it */
82 struct usbip_imported_device
*idev
= &vhci_driver
->idev
[port
];
85 idev
->status
= status
;
89 idev
->busnum
= (devid
>> 16);
90 idev
->devnum
= (devid
& 0x0000ffff);
92 idev
->cdev_list
= dlist_new(sizeof(struct usbip_class_device
));
93 if (!idev
->cdev_list
) {
94 err("init new device");
98 if (idev
->status
!= VDEV_ST_NULL
&& idev
->status
!= VDEV_ST_NOTASSIGNED
) {
99 idev
= imported_device_init(idev
, lbusid
);
101 err("init new device");
108 /* go to the next line */
109 c
= strchr(c
, '\n') + 1;
118 static int check_usbip_device(struct sysfs_class_device
*cdev
)
120 char class_path
[SYSFS_PATH_MAX
]; /* /sys/class/video4linux/video0/device */
121 char dev_path
[SYSFS_PATH_MAX
]; /* /sys/devices/platform/vhci_hcd/usb6/6-1:1.1 */
123 struct usbip_class_device
*usbip_cdev
;
125 snprintf(class_path
, sizeof(class_path
), "%s/device", cdev
->path
);
127 ret
= sysfs_get_link(class_path
, dev_path
, sizeof(dev_path
));
129 if (!strncmp(dev_path
, vhci_driver
->hc_device
->path
,
130 strlen(vhci_driver
->hc_device
->path
))) {
131 /* found usbip device */
132 usbip_cdev
= calloc(1, sizeof(*usbip_cdev
));
134 err("calloc usbip_cdev");
137 dlist_unshift(vhci_driver
->cdev_list
, usbip_cdev
);
138 strncpy(usbip_cdev
->class_path
, class_path
,
139 sizeof(usbip_cdev
->class_path
));
140 strncpy(usbip_cdev
->dev_path
, dev_path
,
141 sizeof(usbip_cdev
->dev_path
));
142 dbg(" found %s %s", class_path
, dev_path
);
150 static int search_class_for_usbip_device(char *cname
)
152 struct sysfs_class
*class;
153 struct dlist
*cdev_list
;
154 struct sysfs_class_device
*cdev
;
157 class = sysfs_open_class(cname
);
163 dbg("class %s", class->name
);
165 cdev_list
= sysfs_get_class_devices(class);
170 dlist_for_each_data(cdev_list
, cdev
, struct sysfs_class_device
) {
171 dbg(" cdev %s", cdev
->name
);
172 ret
= check_usbip_device(cdev
);
178 sysfs_close_class(class);
184 static int refresh_class_device_list(void)
187 struct dlist
*cname_list
;
190 /* search under /sys/class */
191 cname_list
= sysfs_open_directory_list("/sys/class");
193 err("open class directory");
197 dlist_for_each_data(cname_list
, cname
, char) {
198 ret
= search_class_for_usbip_device(cname
);
200 sysfs_close_list(cname_list
);
205 sysfs_close_list(cname_list
);
207 /* seach under /sys/block */
208 ret
= search_class_for_usbip_device(SYSFS_BLOCK_NAME
);
216 static int refresh_imported_device_list(void)
218 struct sysfs_attribute
*attr_status
;
221 attr_status
= sysfs_get_device_attr(vhci_driver
->hc_device
, "status");
223 err("get attr %s of %s", "status", vhci_driver
->hc_device
->name
);
227 dbg("name %s, path %s, len %d, method %d\n", attr_status
->name
,
228 attr_status
->path
, attr_status
->len
, attr_status
->method
);
230 dbg("%s", attr_status
->value
);
232 return parse_status(attr_status
->value
);
235 static int get_nports(void)
238 struct sysfs_attribute
*attr_status
;
240 attr_status
= sysfs_get_device_attr(vhci_driver
->hc_device
, "status");
242 err("get attr %s of %s", "status", vhci_driver
->hc_device
->name
);
246 dbg("name %s, path %s, len %d, method %d\n", attr_status
->name
,
247 attr_status
->path
, attr_status
->len
, attr_status
->method
);
249 dbg("%s", attr_status
->value
);
254 /* skip a header line */
255 c
= strchr(attr_status
->value
, '\n') + 1;
258 /* go to the next line */
259 c
= strchr(c
, '\n') + 1;
267 static int get_hc_busid(char *sysfs_mntpath
, char *hc_busid
)
269 struct sysfs_driver
*sdriver
;
270 char sdriver_path
[SYSFS_PATH_MAX
];
272 struct sysfs_device
*hc_dev
;
273 struct dlist
*hc_devs
;
277 snprintf(sdriver_path
, SYSFS_PATH_MAX
, "%s/%s/platform/%s/%s",
278 sysfs_mntpath
, SYSFS_BUS_NAME
, SYSFS_DRIVERS_NAME
,
279 USBIP_VHCI_DRV_NAME
);
281 sdriver
= sysfs_open_driver_path(sdriver_path
);
283 info("%s is not found", sdriver_path
);
284 info("please load " USBIP_CORE_MOD_NAME
".ko and "
285 USBIP_VHCI_DRV_NAME
".ko!");
289 hc_devs
= sysfs_get_driver_devices(sdriver
);
295 /* assume only one vhci_hcd */
296 dlist_for_each_data(hc_devs
, hc_dev
, struct sysfs_device
) {
297 strncpy(hc_busid
, hc_dev
->bus_id
, SYSFS_BUS_ID_SIZE
);
302 sysfs_close_driver(sdriver
);
307 err("not found usbip hc");
312 /* ---------------------------------------------------------------------- */
314 int usbip_vhci_driver_open(void)
317 char hc_busid
[SYSFS_BUS_ID_SIZE
];
319 vhci_driver
= (struct usbip_vhci_driver
*) calloc(1, sizeof(*vhci_driver
));
321 err("alloc vhci_driver");
325 ret
= sysfs_get_mnt_path(vhci_driver
->sysfs_mntpath
, SYSFS_PATH_MAX
);
327 err("sysfs must be mounted");
331 ret
= get_hc_busid(vhci_driver
->sysfs_mntpath
, hc_busid
);
335 /* will be freed in usbip_driver_close() */
336 vhci_driver
->hc_device
= sysfs_open_device("platform", hc_busid
);
337 if (!vhci_driver
->hc_device
) {
338 err("get sysfs vhci_driver");
342 vhci_driver
->nports
= get_nports();
344 info("%d ports available\n", vhci_driver
->nports
);
346 vhci_driver
->cdev_list
= dlist_new(sizeof(struct usbip_class_device
));
347 if (!vhci_driver
->cdev_list
)
350 if (refresh_class_device_list())
353 if (refresh_imported_device_list())
361 if (vhci_driver
->cdev_list
)
362 dlist_destroy(vhci_driver
->cdev_list
);
363 if (vhci_driver
->hc_device
)
364 sysfs_close_device(vhci_driver
->hc_device
);
373 void usbip_vhci_driver_close()
378 if (vhci_driver
->cdev_list
)
379 dlist_destroy(vhci_driver
->cdev_list
);
381 for (int i
= 0; i
< vhci_driver
->nports
; i
++) {
382 if (vhci_driver
->idev
[i
].cdev_list
)
383 dlist_destroy(vhci_driver
->idev
[i
].cdev_list
);
386 if (vhci_driver
->hc_device
)
387 sysfs_close_device(vhci_driver
->hc_device
);
394 int usbip_vhci_refresh_device_list(void)
396 if (vhci_driver
->cdev_list
)
397 dlist_destroy(vhci_driver
->cdev_list
);
400 for (int i
= 0; i
< vhci_driver
->nports
; i
++) {
401 if (vhci_driver
->idev
[i
].cdev_list
)
402 dlist_destroy(vhci_driver
->idev
[i
].cdev_list
);
405 vhci_driver
->cdev_list
= dlist_new(sizeof(struct usbip_class_device
));
406 if (!vhci_driver
->cdev_list
)
409 if (refresh_class_device_list())
412 if (refresh_imported_device_list())
417 if (vhci_driver
->cdev_list
)
418 dlist_destroy(vhci_driver
->cdev_list
);
420 for (int i
= 0; i
< vhci_driver
->nports
; i
++) {
421 if (vhci_driver
->idev
[i
].cdev_list
)
422 dlist_destroy(vhci_driver
->idev
[i
].cdev_list
);
425 err("refresh device list");
430 int usbip_vhci_get_free_port(void)
432 for (int i
= 0; i
< vhci_driver
->nports
; i
++) {
433 if (vhci_driver
->idev
[i
].status
== VDEV_ST_NULL
)
440 int usbip_vhci_attach_device2(uint8_t port
, int sockfd
, uint32_t devid
,
442 struct sysfs_attribute
*attr_attach
;
443 char buff
[200]; /* what size should be ? */
446 attr_attach
= sysfs_get_device_attr(vhci_driver
->hc_device
, "attach");
452 snprintf(buff
, sizeof(buff
), "%u %u %u %u",
453 port
, sockfd
, devid
, speed
);
454 dbg("writing: %s", buff
);
456 ret
= sysfs_write_attribute(attr_attach
, buff
, strlen(buff
));
458 err("write to attach failed");
462 info("port %d attached", port
);
467 static unsigned long get_devid(uint8_t busnum
, uint8_t devnum
)
469 return (busnum
<< 16) | devnum
;
472 /* will be removed */
473 int usbip_vhci_attach_device(uint8_t port
, int sockfd
, uint8_t busnum
,
474 uint8_t devnum
, uint32_t speed
)
476 int devid
= get_devid(busnum
, devnum
);
478 return usbip_vhci_attach_device2(port
, sockfd
, devid
, speed
);
481 int usbip_vhci_detach_device(uint8_t port
)
483 struct sysfs_attribute
*attr_detach
;
484 char buff
[200]; /* what size should be ? */
487 attr_detach
= sysfs_get_device_attr(vhci_driver
->hc_device
, "detach");
493 snprintf(buff
, sizeof(buff
), "%u", port
);
494 dbg("writing to detach");
495 dbg("writing: %s", buff
);
497 ret
= sysfs_write_attribute(attr_detach
, buff
, strlen(buff
));
499 err("write to detach failed");
503 info("port %d detached", port
);
This page took 0.040895 seconds and 4 git commands to generate.