Date: Mon, 14 Jul 2008 13:46:27 GMT From: Hans Petter Selasky <hselasky@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 145227 for review Message-ID: <200807141346.m6EDkR76017081@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=145227 Change 145227 by hselasky@hselasky_laptop001 on 2008/07/14 13:45:42 Implement new way to read out USB devices present after advice from PHK. Affected files ... .. //depot/projects/usb/src/sys/dev/usb2/core/usb2_core.h#12 edit .. //depot/projects/usb/src/sys/dev/usb2/core/usb2_dev.c#17 edit .. //depot/projects/usb/src/sys/dev/usb2/core/usb2_dev.h#10 edit .. //depot/projects/usb/src/sys/dev/usb2/core/usb2_device.c#14 edit .. //depot/projects/usb/src/sys/dev/usb2/core/usb2_device.h#5 edit .. //depot/projects/usb/src/sys/dev/usb2/core/usb2_generic.c#14 edit .. //depot/projects/usb/src/sys/dev/usb2/include/usb2_ioctl.h#10 edit Differences ... ==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_core.h#12 (text+ko) ==== @@ -376,7 +376,6 @@ MALLOC_DECLARE(M_USBHC); extern struct mtx usb2_ref_lock; -extern struct mtx usb2_sym_lock; /* typedefs */ ==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_dev.c#17 (text+ko) ==== @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2006 Hans Petter Selasky. All rights reserved. + * Copyright (c) 2006-2008 Hans Petter Selasky. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -87,6 +87,7 @@ static d_fdopen_t usb2_fdopen; static d_close_t usb2_close; +static d_ioctl_t usb2_ioctl; static fo_rdwr_t usb2_read_f; static fo_rdwr_t usb2_write_f; @@ -113,6 +114,7 @@ .d_version = D_VERSION, .d_fdopen = usb2_fdopen, .d_close = usb2_close, + .d_ioctl = usb2_ioctl, .d_name = "usb", .d_flags = D_TRACKCLOSE, }; @@ -136,9 +138,9 @@ static void *usb2_old_f_data; static struct fileops *usb2_old_f_ops; static TAILQ_HEAD(, usb2_symlink) usb2_sym_head; +static struct sx usb2_sym_lock; struct mtx usb2_ref_lock; -struct mtx usb2_sym_lock; static uint32_t usb2_path_convert_one(const char **pp) @@ -984,7 +986,8 @@ * usb2_fdopen - cdev callback *------------------------------------------------------------------------*/ static int -usb2_fdopen(struct cdev *dev, int xxx_oflags, struct thread *td, struct file *fp) +usb2_fdopen(struct cdev *dev, int xxx_oflags, struct thread *td, + struct file *fp) { struct usb2_location loc; uint32_t devloc; @@ -994,7 +997,7 @@ DPRINTF(1, "oflags=0x%08x\n", xxx_oflags); devloc = usb2_last_devloc; - usb2_last_devloc = (0 - 1); /* reset "usb2_devloc" */ + usb2_last_devloc = (0 - 1); /* reset "usb2_last_devloc" */ if (fp == NULL) { DPRINTF(1, "fp == NULL\n"); @@ -1021,8 +1024,11 @@ /* should not happen */ return (EPERM); } - if (devloc == (uint32_t)(0 - 1)) { - /* tried to open /dev/usb */ + if (devloc == (uint32_t)(0 - 2)) { + /* tried to open "/dev/usb" */ + return (0); + } else if (devloc == (uint32_t)(0 - 1)) { + /* tried to open "/dev/usb " */ DPRINTF(1, "no devloc\n"); return (ENXIO); } @@ -1090,6 +1096,30 @@ } /*------------------------------------------------------------------------* + * usb2_close - cdev callback + *------------------------------------------------------------------------*/ +static int +usb2_ioctl(struct cdev *dev, u_long cmd, caddr_t data, + int fflag, struct thread *td) +{ + int err; + + switch (cmd) { + case USB_READ_DIR:{ + struct usb2_read_dir *urd = (void *)data; + + err = usb2_read_symlink(urd->urd_data, + urd->urd_startentry, urd->urd_maxlen); + break; + } + default: + err = ENOTTY; + break; + } + return (err); +} + +/*------------------------------------------------------------------------* * usb2_clone - cdev callback * * This function is the kernel clone callback for "/dev/usbX.Y". @@ -1116,8 +1146,12 @@ usb2_last_devloc = usb2_lookup_symlink(name, namelen); } else { - usb2_last_devloc = - usb2_path_convert(name + USB_DNAME_LEN); + if (namelen == USB_DNAME_LEN) { + usb2_last_devloc = (uint32_t)(0 - 2); + } else { + usb2_last_devloc = + usb2_path_convert(name + USB_DNAME_LEN); + } } if (usb2_last_devloc == (uint32_t)(0 - 1)) { @@ -1133,7 +1167,7 @@ usb2_dev_init(void *arg) { mtx_init(&usb2_ref_lock, "USB ref mutex", NULL, MTX_DEF); - mtx_init(&usb2_sym_lock, "USB sym mutex", NULL, MTX_DEF); + sx_init(&usb2_sym_lock, "USB sym mutex"); TAILQ_INIT(&usb2_sym_head); /* check the UGEN methods */ @@ -1146,7 +1180,11 @@ static void usb2_dev_init_post(void *arg) { - /* create a dummy device so that we are visible */ + /* + * Create a dummy device so that we are visible. This device + * should never be opened. Therefore a space character is + * appended after the USB device name. + */ usb2_dev = make_dev(&usb2_devsw, 0, UID_ROOT, GID_OPERATOR, 0000, USB_DEVICE_NAME " "); if (usb2_dev == NULL) { @@ -1173,6 +1211,7 @@ usb2_dev = NULL; } mtx_destroy(&usb2_ref_lock); + sx_destroy(&usb2_sym_lock); return; } @@ -2298,9 +2337,9 @@ va_end(ap); ps->src_len = strlen(ps->src_path); - mtx_lock(&usb2_sym_lock); + sx_xlock(&usb2_sym_lock); TAILQ_INSERT_TAIL(&usb2_sym_head, ps, sym_entry); - mtx_unlock(&usb2_sym_lock); + sx_unlock(&usb2_sym_lock); return (ps); } @@ -2313,9 +2352,9 @@ if (ps == NULL) { return; } - mtx_lock(&usb2_sym_lock); + sx_xlock(&usb2_sym_lock); TAILQ_REMOVE(&usb2_sym_head, ps, sym_entry); - mtx_unlock(&usb2_sym_lock); + sx_unlock(&usb2_sym_lock); free(ps, M_USBDEV); return; @@ -2336,7 +2375,7 @@ struct usb2_symlink *ps; uint32_t temp; - mtx_lock(&usb2_sym_lock); + sx_xlock(&usb2_sym_lock); TAILQ_FOREACH(ps, &usb2_sym_head, sym_entry) { @@ -2349,14 +2388,109 @@ if (USB_DNAME_LEN > ps->dst_len) continue; - if (strncmp(ps->dst_path, USB_DEVICE_NAME, USB_DNAME_LEN)) + if (memcmp(ps->dst_path, USB_DEVICE_NAME, USB_DNAME_LEN)) continue; temp = usb2_path_convert(ps->dst_path + USB_DNAME_LEN); - mtx_unlock(&usb2_sym_lock); + sx_unlock(&usb2_sym_lock); return (temp); } - mtx_unlock(&usb2_sym_lock); + sx_unlock(&usb2_sym_lock); return (0 - 1); } + +/*------------------------------------------------------------------------* + * usb2_read_symlink + * + * Return value: + * 0: Success + * Else: Failure + *------------------------------------------------------------------------*/ +int +usb2_read_symlink(uint8_t *user_ptr, uint32_t startentry, uint32_t user_len) +{ + struct usb2_symlink *ps; + uint32_t curoff = 0; + uint32_t temp; + uint32_t delta = 0; + uint8_t len; + int error = 0; + + sx_xlock(&usb2_sym_lock); + + TAILQ_FOREACH(ps, &usb2_sym_head, sym_entry) { + + temp = ps->src_len + ps->dst_len + 3; + + if (temp > 255) { + continue; + } + if (startentry != 0) { + startentry--; + curoff += temp; + continue; + } + if (temp > user_len) { + /* out of buffer space */ + break; + } + len = temp; + + /* copy out total length */ + + error = copyout(&len, + USB_ADD_BYTES(user_ptr, delta), 1); + if (error) { + break; + } + delta += 1; + + /* copy out source string */ + + error = copyout(ps->src_path, + USB_ADD_BYTES(user_ptr, delta), ps->src_len); + if (error) { + break; + } + len = 0; + delta += ps->src_len; + error = copyout(&len, + USB_ADD_BYTES(user_ptr, delta), 1); + if (error) { + break; + } + delta += 1; + + /* copy out destination string */ + + error = copyout(ps->dst_path, + USB_ADD_BYTES(user_ptr, delta), ps->dst_len); + if (error) { + break; + } + len = 0; + delta += ps->dst_len; + error = copyout(&len, + USB_ADD_BYTES(user_ptr, delta), 1); + if (error) { + break; + } + delta += 1; + + curoff += temp; + user_len -= temp; + } + + /* a zero length entry indicates the end */ + + if ((user_len != 0) && (error == 0)) { + + len = 0; + + error = copyout(&len, + USB_ADD_BYTES(user_ptr, delta), 1); + } + sx_unlock(&usb2_sym_lock); + return (error); +} ==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_dev.h#10 (text+ko) ==== @@ -140,5 +140,6 @@ struct usb2_symlink *usb2_alloc_symlink(const char *target, const char *fmt,...); void usb2_free_symlink(struct usb2_symlink *ps); uint32_t usb2_lookup_symlink(const char *src_ptr, uint8_t src_len); +int usb2_read_symlink(uint8_t *user_ptr, uint32_t startentry, uint32_t user_len); #endif /* _USB2_DEV_H_ */ ==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_device.c#14 (text+ko) ==== @@ -1327,6 +1327,7 @@ udev->depth = depth; udev->bus = bus; udev->address = USB_START_ADDR; /* default value */ + udev->plugtime = (uint32_t)ticks; /* we are not ready yet */ udev->refcount = 1; @@ -1614,7 +1615,7 @@ /* ignore */ } udev->ugen_symlink = - make_dev_symlink(scratch_ptr, "ugen%u.%u", + usb2_alloc_symlink(scratch_ptr, "ugen%u.%u", device_get_unit(udev->bus->bdev), udev->device_index); @@ -1653,7 +1654,7 @@ * Destroy UGEN symlink, if any */ if (udev->ugen_symlink) { - destroy_dev(udev->ugen_symlink); + usb2_free_symlink(udev->ugen_symlink); udev->ugen_symlink = NULL; } /* ==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_device.h#5 (text+ko) ==== @@ -26,6 +26,8 @@ #ifndef _USB2_DEVICE_H_ #define _USB2_DEVICE_H_ +struct usb2_symlink; + #define USB_DEFAULT_XFER_MAX 2 struct usb2_clear_stall_msg { @@ -108,7 +110,9 @@ struct usb2_temp_data *usb2_template_ptr; struct usb2_pipe *pipe_curr; /* current clear stall pipe */ struct usb2_fifo *fifo[USB_FIFO_MAX]; - struct cdev *ugen_symlink; /* our generic symlink */ + struct usb2_symlink *ugen_symlink; /* our generic symlink */ + + uint32_t plugtime; /* copy of "ticks" */ uint16_t refcount; #define USB_DEV_REF_MAX 0xffff ==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_generic.c#14 (text+ko) ==== @@ -1890,6 +1890,13 @@ error = ugen_re_enumerate(f); break; + case USB_GET_PLUGTIME:{ + uint32_t *ptime = addr; + + *ptime = f->udev->plugtime; + break; + } + /* ... more IOCTL's to come ! ... --hps */ default: ==== //depot/projects/usb/src/sys/dev/usb2/include/usb2_ioctl.h#10 (text+ko) ==== @@ -32,6 +32,12 @@ #define USB_DEVICE_NAME "usb" +struct usb2_read_dir { + void *urd_data; + uint32_t urd_startentry; + uint32_t urd_maxlen; +}; + struct usb2_ctl_request { void *ucr_data; uint16_t ucr_flags; @@ -214,6 +220,8 @@ #define USB_RELEASE_INTERFACE _IOW ('U', 123, int) #define USB_IFACE_DRIVER_ACTIVE _IOW ('U', 124, int) #define USB_IFACE_DRIVER_DETACH _IOW ('U', 125, int) +#define USB_GET_PLUGTIME _IOR ('U', 126, uint32_t) +#define USB_READ_DIR _IOW ('U', 127, struct usb2_read_dir) /* Modem device */ #define USB_GET_CM_OVER_DATA _IOR ('U', 130, int)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200807141346.m6EDkR76017081>