Home | History | Annotate | Line # | Download | only in usb
utoppy.c revision 1.8.10.4
      1  1.8.10.4     itohy /*	$NetBSD: utoppy.c,v 1.8.10.4 2007/06/18 14:16:58 itohy Exp $	*/
      2       1.1       scw 
      3       1.1       scw /*-
      4       1.1       scw  * Copyright (c) 2006 The NetBSD Foundation, Inc.
      5       1.1       scw  * All rights reserved.
      6       1.1       scw  *
      7       1.1       scw  * This code is derived from software contributed to The NetBSD Foundation
      8       1.1       scw  * by Steve C. Woodford.
      9       1.1       scw  *
     10       1.1       scw  * Redistribution and use in source and binary forms, with or without
     11       1.1       scw  * modification, are permitted provided that the following conditions
     12       1.1       scw  * are met:
     13       1.1       scw  * 1. Redistributions of source code must retain the above copyright
     14       1.1       scw  *    notice, this list of conditions and the following disclaimer.
     15       1.1       scw  * 2. Redistributions in binary form must reproduce the above copyright
     16       1.1       scw  *    notice, this list of conditions and the following disclaimer in the
     17       1.1       scw  *    documentation and/or other materials provided with the distribution.
     18       1.1       scw  * 3. All advertising materials mentioning features or use of this software
     19       1.1       scw  *    must display the following acknowledgement:
     20       1.1       scw  *        This product includes software developed by the NetBSD
     21       1.1       scw  *        Foundation, Inc. and its contributors.
     22       1.1       scw  * 4. Neither the name of The NetBSD Foundation nor the names of its
     23       1.1       scw  *    contributors may be used to endorse or promote products derived
     24       1.1       scw  *    from this software without specific prior written permission.
     25       1.1       scw  *
     26       1.1       scw  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     27       1.1       scw  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     28       1.1       scw  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     29       1.1       scw  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     30       1.1       scw  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     31       1.1       scw  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     32       1.1       scw  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     33       1.1       scw  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     34       1.1       scw  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     35       1.1       scw  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     36       1.1       scw  * POSSIBILITY OF SUCH DAMAGE.
     37       1.1       scw  */
     38       1.1       scw 
     39       1.1       scw #include <sys/cdefs.h>
     40  1.8.10.4     itohy __KERNEL_RCSID(0, "$NetBSD: utoppy.c,v 1.8.10.4 2007/06/18 14:16:58 itohy Exp $");
     41       1.1       scw 
     42       1.1       scw #include <sys/param.h>
     43       1.1       scw #include <sys/systm.h>
     44       1.1       scw #include <sys/proc.h>
     45       1.1       scw #include <sys/kernel.h>
     46       1.1       scw #include <sys/fcntl.h>
     47       1.1       scw #include <sys/device.h>
     48       1.1       scw #include <sys/malloc.h>
     49       1.1       scw #include <sys/ioctl.h>
     50       1.1       scw #include <sys/uio.h>
     51       1.1       scw #include <sys/conf.h>
     52       1.1       scw #include <sys/vnode.h>
     53       1.1       scw 
     54       1.1       scw #include <dev/usb/usb.h>
     55       1.1       scw #include <dev/usb/usbdi.h>
     56       1.1       scw #include <dev/usb/usbdi_util.h>
     57       1.1       scw #include <dev/usb/usbdevs.h>
     58       1.1       scw #include <dev/usb/usb_quirks.h>
     59       1.1       scw #include <dev/usb/utoppy.h>
     60       1.1       scw 
     61       1.1       scw #undef UTOPPY_DEBUG
     62       1.1       scw #ifdef UTOPPY_DEBUG
     63       1.1       scw #define	UTOPPY_DBG_OPEN		0x0001
     64       1.1       scw #define	UTOPPY_DBG_CLOSE	0x0002
     65       1.1       scw #define	UTOPPY_DBG_READ		0x0004
     66       1.1       scw #define	UTOPPY_DBG_WRITE	0x0008
     67       1.1       scw #define	UTOPPY_DBG_IOCTL	0x0010
     68       1.1       scw #define	UTOPPY_DBG_SEND_PACKET	0x0020
     69       1.1       scw #define	UTOPPY_DBG_RECV_PACKET	0x0040
     70       1.1       scw #define	UTOPPY_DBG_ADDPATH	0x0080
     71       1.1       scw #define	UTOPPY_DBG_READDIR	0x0100
     72       1.1       scw #define	UTOPPY_DBG_DUMP		0x0200
     73       1.1       scw #define	DPRINTF(l, m)				\
     74       1.1       scw 		do {				\
     75       1.1       scw 			if (utoppy_debug & l)	\
     76       1.1       scw 				printf m;	\
     77       1.1       scw 		} while (/*CONSTCOND*/0)
     78       1.1       scw static int utoppy_debug = 0;
     79       1.1       scw static void utoppy_dump_packet(const void *, size_t);
     80       1.1       scw #define	DDUMP_PACKET(p, l)					\
     81       1.1       scw 		do {						\
     82       1.1       scw 			if (utoppy_debug & UTOPPY_DBG_DUMP)	\
     83       1.1       scw 				utoppy_dump_packet((p), (l));	\
     84       1.1       scw 		} while (/*CONSTCOND*/0)
     85       1.1       scw #else
     86       1.1       scw #define	DPRINTF(l, m)		/* nothing */
     87       1.1       scw #define	DDUMP_PACKET(p, l)	/* nothing */
     88       1.1       scw #endif
     89       1.1       scw 
     90       1.1       scw 
     91       1.1       scw #define	UTOPPY_CONFIG_NO	1
     92       1.1       scw #define	UTOPPY_NUMENDPOINTS	2
     93       1.1       scw 
     94       1.1       scw #define	UTOPPY_BSIZE		0xffff
     95       1.1       scw #define	UTOPPY_FRAG_SIZE	0x1000
     96       1.1       scw #define	UTOPPY_HEADER_SIZE	8
     97       1.1       scw #define	UTOPPY_SHORT_TIMEOUT	(500)		/* 0.5 seconds */
     98       1.1       scw #define	UTOPPY_LONG_TIMEOUT	(10 * 1000)	/* 10 seconds */
     99       1.1       scw 
    100       1.1       scw /* Protocol Commands and Responses */
    101       1.1       scw #define	UTOPPY_RESP_ERROR		0x0001
    102       1.1       scw #define	UTOPPY_CMD_ACK			0x0002
    103       1.1       scw #define	 UTOPPY_RESP_SUCCESS		UTOPPY_CMD_ACK
    104       1.1       scw #define	UTOPPY_CMD_CANCEL		0x0003
    105       1.1       scw #define	UTOPPY_CMD_READY		0x0100
    106       1.1       scw #define	UTOPPY_CMD_RESET		0x0101
    107       1.1       scw #define	UTOPPY_CMD_TURBO		0x0102
    108       1.1       scw #define	UTOPPY_CMD_STATS		0x1000
    109       1.1       scw #define  UTOPPY_RESP_STATS_DATA		0x1001
    110       1.1       scw #define	UTOPPY_CMD_READDIR		0x1002
    111       1.1       scw #define	 UTOPPY_RESP_READDIR_DATA	0x1003
    112       1.1       scw #define	 UTOPPY_RESP_READDIR_END	0x1004
    113       1.1       scw #define	UTOPPY_CMD_DELETE		0x1005
    114       1.1       scw #define	UTOPPY_CMD_RENAME		0x1006
    115       1.1       scw #define	UTOPPY_CMD_MKDIR		0x1007
    116       1.1       scw #define	UTOPPY_CMD_FILE			0x1008
    117       1.1       scw #define  UTOPPY_FILE_WRITE		0
    118       1.1       scw #define  UTOPPY_FILE_READ		1
    119       1.1       scw #define	 UTOPPY_RESP_FILE_HEADER	0x1009
    120       1.1       scw #define	 UTOPPY_RESP_FILE_DATA		0x100a
    121       1.1       scw #define	 UTOPPY_RESP_FILE_END		0x100b
    122       1.1       scw 
    123       1.1       scw enum utoppy_state {
    124       1.1       scw 	UTOPPY_STATE_CLOSED,
    125       1.1       scw 	UTOPPY_STATE_OPENING,
    126       1.1       scw 	UTOPPY_STATE_IDLE,
    127       1.1       scw 	UTOPPY_STATE_READDIR,
    128       1.1       scw 	UTOPPY_STATE_READFILE,
    129       1.1       scw 	UTOPPY_STATE_WRITEFILE
    130       1.1       scw };
    131       1.1       scw 
    132       1.1       scw struct utoppy_softc {
    133       1.1       scw 	USBBASEDEVICE sc_dev;
    134       1.1       scw 	usbd_device_handle sc_udev;	/* device */
    135       1.1       scw 	usbd_interface_handle sc_iface;	/* interface */
    136       1.1       scw 	int sc_dying;
    137       1.1       scw 	int sc_refcnt;
    138       1.1       scw 
    139       1.1       scw 	enum utoppy_state sc_state;
    140       1.1       scw 	u_int sc_turbo_mode;
    141       1.1       scw 
    142       1.1       scw 	int sc_out;
    143       1.1       scw 	usbd_pipe_handle sc_out_pipe;	/* bulk out pipe */
    144       1.1       scw 	usbd_xfer_handle sc_out_xfer;
    145       1.1       scw 	void *sc_out_buf;
    146       1.1       scw 	void *sc_out_data;
    147       1.1       scw 	uint64_t sc_wr_offset;
    148       1.1       scw 	uint64_t sc_wr_size;
    149       1.1       scw 
    150       1.1       scw 	int sc_in;
    151       1.1       scw 	usbd_pipe_handle sc_in_pipe;	/* bulk in pipe */
    152       1.1       scw 	usbd_xfer_handle sc_in_xfer;
    153       1.1       scw 	void *sc_in_buf;
    154       1.1       scw 	void *sc_in_data;
    155       1.1       scw 	size_t sc_in_len;
    156       1.1       scw 	u_int sc_in_offset;
    157       1.1       scw };
    158       1.1       scw 
    159       1.1       scw struct utoppy_header {
    160       1.1       scw 	uint16_t h_len;
    161       1.1       scw 	uint16_t h_crc;
    162       1.1       scw 	uint16_t h_cmd2;
    163       1.1       scw 	uint16_t h_cmd;
    164       1.1       scw 	uint8_t h_data[0];
    165       1.1       scw };
    166       1.1       scw #define	UTOPPY_OUT_INIT(sc)					\
    167       1.1       scw 	do {							\
    168       1.1       scw 		struct utoppy_header *_h = sc->sc_out_data;	\
    169       1.1       scw 		_h->h_len = 0;					\
    170       1.1       scw 	} while (/*CONSTCOND*/0)
    171       1.1       scw 
    172       1.1       scw #define	UTOPPY_MJD_1970 40587u	/* MJD value for Jan 1 00:00:00 1970 */
    173       1.1       scw 
    174       1.1       scw #define	UTOPPY_FTYPE_DIR	1
    175       1.1       scw #define	UTOPPY_FTYPE_FILE	2
    176       1.1       scw 
    177       1.1       scw #define	UTOPPY_IN_DATA(sc)	\
    178       1.1       scw  ((void*)&(((uint8_t*)(sc)->sc_in_data)[(sc)->sc_in_offset+UTOPPY_HEADER_SIZE]))
    179       1.1       scw 
    180       1.1       scw dev_type_open(utoppyopen);
    181       1.1       scw dev_type_close(utoppyclose);
    182       1.1       scw dev_type_read(utoppyread);
    183       1.1       scw dev_type_write(utoppywrite);
    184       1.1       scw dev_type_ioctl(utoppyioctl);
    185       1.1       scw 
    186       1.1       scw const struct cdevsw utoppy_cdevsw = {
    187       1.1       scw 	utoppyopen, utoppyclose, utoppyread, utoppywrite, utoppyioctl,
    188       1.6  christos 	nostop, notty, nopoll, nommap, nokqfilter, D_OTHER,
    189       1.1       scw };
    190       1.1       scw 
    191       1.1       scw #define	UTOPPYUNIT(n)	(minor(n))
    192       1.1       scw 
    193       1.1       scw USB_DECLARE_DRIVER(utoppy);
    194       1.1       scw 
    195       1.1       scw USB_MATCH(utoppy)
    196       1.1       scw {
    197       1.1       scw 	USB_MATCH_START(utoppy, uaa);
    198       1.1       scw 
    199  1.8.10.4     itohy #ifndef USB_USE_IFATTACH
    200       1.1       scw 	if (uaa->iface == NULL)
    201       1.1       scw 		return (UMATCH_NONE);
    202  1.8.10.4     itohy #endif /* USB_USE_IFATTACH */
    203       1.1       scw 
    204       1.1       scw 	if (uaa->vendor == USB_VENDOR_TOPFIELD &&
    205       1.1       scw 	    uaa->product == USB_PRODUCT_TOPFIELD_TF5000PVR)
    206       1.1       scw 		return (UMATCH_VENDOR_PRODUCT);
    207       1.1       scw 
    208       1.1       scw 	return (UMATCH_NONE);
    209       1.1       scw }
    210       1.1       scw 
    211       1.1       scw USB_ATTACH(utoppy)
    212       1.1       scw {
    213       1.1       scw 	USB_ATTACH_START(utoppy, sc, uaa);
    214       1.1       scw 	usbd_device_handle dev = uaa->device;
    215  1.8.10.4     itohy #ifdef USB_USE_IFATTACH
    216  1.8.10.4     itohy 	usbd_interface_handle iface;
    217  1.8.10.4     itohy #endif /* USB_USE_IFATTACH */
    218       1.1       scw 	usb_endpoint_descriptor_t *ed;
    219       1.1       scw 	char *devinfop;
    220       1.1       scw 	u_int8_t epcount;
    221       1.1       scw 	int i;
    222       1.1       scw 
    223       1.1       scw 	devinfop = usbd_devinfo_alloc(dev, 0);
    224       1.1       scw 	USB_ATTACH_SETUP;
    225       1.1       scw 	printf("%s: %s\n", USBDEVNAME(sc->sc_dev), devinfop);
    226       1.1       scw 	usbd_devinfo_free(devinfop);
    227       1.1       scw 
    228       1.1       scw 	sc->sc_dying = 0;
    229       1.1       scw 	sc->sc_refcnt = 0;
    230       1.1       scw 	sc->sc_udev = dev;
    231       1.1       scw 
    232  1.8.10.4     itohy #ifdef USB_USE_IFATTACH
    233  1.8.10.4     itohy 	if (usbd_set_config_index(dev, 0, 1)
    234  1.8.10.4     itohy 	    || usbd_device2interface_handle(dev, 0, &iface)) {
    235  1.8.10.4     itohy 		printf("%s: Configuration failed\n", USBDEVNAME(sc->sc_dev));
    236  1.8.10.4     itohy 		USB_ATTACH_ERROR_RETURN;
    237  1.8.10.4     itohy 	}
    238  1.8.10.4     itohy #endif /* USB_USE_IFATTACH */
    239  1.8.10.4     itohy 
    240       1.1       scw 	epcount = 0;
    241  1.8.10.4     itohy #ifndef USB_USE_IFATTACH
    242       1.1       scw 	(void) usbd_endpoint_count(uaa->iface, &epcount);
    243  1.8.10.4     itohy #else
    244  1.8.10.4     itohy 	(void) usbd_endpoint_count(iface, &epcount);
    245  1.8.10.4     itohy #endif /* USB_USE_IFATTACH */
    246       1.1       scw 	if (epcount != UTOPPY_NUMENDPOINTS) {
    247       1.1       scw 		printf("%s: Expected %d endpoints, got %d\n",
    248       1.1       scw 		    USBDEVNAME(sc->sc_dev), UTOPPY_NUMENDPOINTS, epcount);
    249       1.1       scw 		USB_ATTACH_ERROR_RETURN;
    250       1.1       scw 	}
    251       1.1       scw 
    252       1.1       scw 	sc->sc_in = -1;
    253       1.1       scw 	sc->sc_out = -1;
    254       1.1       scw 
    255       1.1       scw 	for (i = 0; i < epcount; i++) {
    256  1.8.10.4     itohy #ifndef USB_USE_IFATTACH
    257       1.1       scw 		ed = usbd_interface2endpoint_descriptor(uaa->iface, i);
    258  1.8.10.4     itohy #else
    259  1.8.10.4     itohy 		ed = usbd_interface2endpoint_descriptor(iface, i);
    260  1.8.10.4     itohy #endif /* USB_USE_IFATTACH */
    261       1.1       scw 		if (ed == NULL) {
    262       1.1       scw 			printf("%s: couldn't get ep %d\n",
    263       1.1       scw 			    USBDEVNAME(sc->sc_dev), i);
    264       1.1       scw 			USB_ATTACH_ERROR_RETURN;
    265       1.1       scw 		}
    266       1.1       scw 
    267       1.1       scw 		if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
    268       1.1       scw 		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
    269       1.1       scw 			sc->sc_in = ed->bEndpointAddress;
    270       1.1       scw 		} else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
    271       1.1       scw 			   UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
    272       1.1       scw 			sc->sc_out = ed->bEndpointAddress;
    273       1.1       scw 		}
    274       1.1       scw 	}
    275       1.1       scw 
    276       1.1       scw 	if (sc->sc_out == -1 || sc->sc_in == -1) {
    277       1.1       scw 		printf("%s: could not find bulk in/out endpoints\n",
    278       1.1       scw 		    USBDEVNAME(sc->sc_dev));
    279       1.1       scw 		sc->sc_dying = 1;
    280       1.1       scw 		USB_ATTACH_ERROR_RETURN;
    281       1.1       scw 	}
    282       1.1       scw 
    283  1.8.10.4     itohy #ifndef USB_USE_IFATTACH
    284       1.1       scw 	sc->sc_iface = uaa->iface;
    285  1.8.10.4     itohy #else
    286  1.8.10.4     itohy 	sc->sc_iface = iface;
    287  1.8.10.4     itohy #endif /* USB_USE_IFATTACH */
    288       1.1       scw 	sc->sc_udev = dev;
    289       1.1       scw 
    290       1.1       scw 	usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
    291       1.1       scw 			   USBDEV(sc->sc_dev));
    292       1.1       scw 
    293       1.1       scw 	USB_ATTACH_SUCCESS_RETURN;
    294       1.1       scw }
    295       1.1       scw 
    296       1.1       scw int
    297       1.1       scw utoppy_activate(device_ptr_t self, enum devact act)
    298       1.1       scw {
    299       1.1       scw 	struct utoppy_softc *sc = (struct utoppy_softc *)self;
    300       1.1       scw 
    301       1.1       scw 	switch (act) {
    302       1.1       scw 	case DVACT_ACTIVATE:
    303       1.1       scw 		return (EOPNOTSUPP);
    304       1.1       scw 
    305       1.1       scw 	case DVACT_DEACTIVATE:
    306       1.1       scw 		sc->sc_dying = 1;
    307       1.1       scw 		break;
    308       1.1       scw 	}
    309       1.1       scw 	return (0);
    310       1.1       scw }
    311       1.1       scw 
    312       1.1       scw USB_DETACH(utoppy)
    313       1.1       scw {
    314       1.1       scw 	USB_DETACH_START(utoppy, sc);
    315       1.1       scw 	int maj, mn;
    316       1.1       scw 	int s;
    317       1.1       scw 
    318       1.1       scw 	sc->sc_dying = 1;
    319       1.1       scw 	if (sc->sc_out_pipe != NULL)
    320       1.1       scw 		usbd_abort_pipe(sc->sc_out_pipe);
    321       1.1       scw 	if (sc->sc_in_pipe != NULL)
    322       1.1       scw 		usbd_abort_pipe(sc->sc_in_pipe);
    323       1.1       scw 
    324       1.1       scw 	if (sc->sc_in_xfer != NULL)
    325       1.1       scw 		usbd_free_xfer(sc->sc_in_xfer);
    326       1.1       scw 	if (sc->sc_out_xfer != NULL)
    327       1.1       scw 		usbd_free_xfer(sc->sc_out_xfer);
    328       1.1       scw 
    329  1.8.10.2     itohy 	if (sc->sc_out_pipe != NULL)
    330  1.8.10.2     itohy 		usbd_close_pipe(sc->sc_out_pipe);
    331  1.8.10.2     itohy 	if (sc->sc_in_pipe != NULL)
    332  1.8.10.2     itohy 		usbd_close_pipe(sc->sc_in_pipe);
    333  1.8.10.2     itohy 
    334       1.1       scw 	s = splusb();
    335       1.1       scw 	if (--sc->sc_refcnt >= 0)
    336       1.1       scw 		usb_detach_wait(USBDEV(sc->sc_dev));
    337       1.1       scw 	splx(s);
    338       1.1       scw 
    339       1.1       scw 	/* locate the major number */
    340       1.1       scw 	maj = cdevsw_lookup_major(&utoppy_cdevsw);
    341       1.1       scw 
    342       1.1       scw 	/* Nuke the vnodes for any open instances (calls close). */
    343       1.1       scw 	mn = self->dv_unit;
    344       1.1       scw 	vdevgone(maj, mn, mn, VCHR);
    345       1.1       scw 
    346       1.1       scw 	usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
    347       1.1       scw 			   USBDEV(sc->sc_dev));
    348       1.1       scw 
    349       1.1       scw 	return (0);
    350       1.1       scw }
    351       1.1       scw 
    352       1.1       scw static const uint16_t utoppy_crc16_lookup[] = {
    353       1.1       scw 	0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241,
    354       1.1       scw 	0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440,
    355       1.1       scw 	0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40,
    356       1.1       scw 	0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841,
    357       1.1       scw 	0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40,
    358       1.1       scw 	0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41,
    359       1.1       scw 	0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641,
    360       1.1       scw 	0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040,
    361       1.1       scw 	0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240,
    362       1.1       scw 	0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441,
    363       1.1       scw 	0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41,
    364       1.1       scw 	0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840,
    365       1.1       scw 	0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41,
    366       1.1       scw 	0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40,
    367       1.1       scw 	0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640,
    368       1.1       scw 	0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041,
    369       1.1       scw 	0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240,
    370       1.1       scw 	0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441,
    371       1.1       scw 	0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41,
    372       1.1       scw 	0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840,
    373       1.1       scw 	0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41,
    374       1.1       scw 	0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40,
    375       1.1       scw 	0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640,
    376       1.1       scw 	0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041,
    377       1.1       scw 	0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241,
    378       1.1       scw 	0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440,
    379       1.1       scw 	0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40,
    380       1.1       scw 	0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841,
    381       1.1       scw 	0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40,
    382       1.1       scw 	0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41,
    383       1.1       scw 	0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641,
    384       1.1       scw 	0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040
    385       1.1       scw };
    386       1.1       scw 
    387       1.1       scw #define	UTOPPY_CRC16(ccrc,b)	\
    388       1.1       scw 	(utoppy_crc16_lookup[((ccrc) ^ (b)) & 0xffu] ^ ((ccrc) >> 8))
    389       1.1       scw 
    390       1.1       scw static const int utoppy_usbdstatus_lookup[] = {
    391       1.1       scw 	0,		/* USBD_NORMAL_COMPLETION */
    392       1.1       scw 	EINPROGRESS,	/* USBD_IN_PROGRESS */
    393       1.1       scw 	EALREADY,	/* USBD_PENDING_REQUESTS */
    394       1.1       scw 	EAGAIN,		/* USBD_NOT_STARTED */
    395       1.1       scw 	EINVAL,		/* USBD_INVAL */
    396       1.1       scw 	ENOMEM,		/* USBD_NOMEM */
    397       1.1       scw 	ECONNRESET,	/* USBD_CANCELLED */
    398       1.1       scw 	EFAULT,		/* USBD_BAD_ADDRESS */
    399       1.1       scw 	EBUSY,		/* USBD_IN_USE */
    400       1.1       scw 	EADDRNOTAVAIL,	/* USBD_NO_ADDR */
    401       1.1       scw 	ENETDOWN,	/* USBD_SET_ADDR_FAILED */
    402       1.1       scw 	EIO,		/* USBD_NO_POWER */
    403       1.1       scw 	EMLINK,		/* USBD_TOO_DEEP */
    404       1.1       scw 	EIO,		/* USBD_IOERROR */
    405       1.1       scw 	ENXIO,		/* USBD_NOT_CONFIGURED */
    406       1.1       scw 	ETIMEDOUT,	/* USBD_TIMEOUT */
    407       1.1       scw 	EBADMSG,	/* USBD_SHORT_XFER */
    408       1.1       scw 	EHOSTDOWN,	/* USBD_STALLED */
    409       1.1       scw 	EINTR		/* USBD_INTERRUPTED */
    410       1.1       scw };
    411       1.1       scw 
    412       1.1       scw static __inline int
    413       1.1       scw utoppy_usbd_status2errno(usbd_status err)
    414       1.1       scw {
    415       1.1       scw 
    416       1.1       scw 	if (err >= USBD_ERROR_MAX)
    417       1.1       scw 		return (EFAULT);
    418       1.1       scw 	return (utoppy_usbdstatus_lookup[err]);
    419       1.1       scw }
    420       1.1       scw 
    421       1.1       scw #ifdef UTOPPY_DEBUG
    422       1.1       scw static const char *
    423       1.1       scw utoppy_state_string(enum utoppy_state state)
    424       1.1       scw {
    425       1.1       scw 	const char *str;
    426       1.1       scw 
    427       1.1       scw 	switch (state) {
    428       1.1       scw 	case UTOPPY_STATE_CLOSED:
    429       1.1       scw 		str = "CLOSED";
    430       1.1       scw 		break;
    431       1.1       scw 	case UTOPPY_STATE_OPENING:
    432       1.1       scw 		str = "OPENING";
    433       1.1       scw 		break;
    434       1.1       scw 	case UTOPPY_STATE_IDLE:
    435       1.1       scw 		str = "IDLE";
    436       1.1       scw 		break;
    437       1.1       scw 	case UTOPPY_STATE_READDIR:
    438       1.1       scw 		str = "READ DIRECTORY";
    439       1.1       scw 		break;
    440       1.1       scw 	case UTOPPY_STATE_READFILE:
    441       1.1       scw 		str = "READ FILE";
    442       1.1       scw 		break;
    443       1.1       scw 	case UTOPPY_STATE_WRITEFILE:
    444       1.1       scw 		str = "WRITE FILE";
    445       1.1       scw 		break;
    446       1.1       scw 	default:
    447       1.1       scw 		str = "INVALID!";
    448       1.1       scw 		break;
    449       1.1       scw 	}
    450       1.1       scw 
    451       1.1       scw 	return (str);
    452       1.1       scw }
    453       1.1       scw 
    454       1.1       scw static void
    455       1.1       scw utoppy_dump_packet(const void *b, size_t len)
    456       1.1       scw {
    457       1.1       scw 	const uint8_t *buf = b, *l;
    458       1.1       scw 	uint8_t c;
    459       1.1       scw 	size_t i, j;
    460       1.1       scw 
    461       1.1       scw 	if (len == 0)
    462       1.1       scw 		return;
    463       1.1       scw 
    464       1.1       scw 	len = min(len, 256);
    465       1.1       scw 
    466       1.1       scw 	printf("00: ");
    467       1.1       scw 
    468       1.1       scw 	for (i = 0, l = buf; i < len; i++) {
    469       1.1       scw 		printf("%02x ", *buf++);
    470       1.1       scw 
    471       1.1       scw 		if ((i % 16) == 15) {
    472       1.1       scw 			for (j = 0; j < 16; j++) {
    473       1.1       scw 				c = *l++;
    474       1.1       scw 				if (c < ' ' || c > 0x7e)
    475       1.1       scw 					c = '.';
    476       1.1       scw 				printf("%c", c);
    477       1.1       scw 			}
    478       1.1       scw 
    479       1.1       scw 			printf("\n");
    480       1.1       scw 			l = buf;
    481       1.1       scw 
    482       1.1       scw 			if ((i + 1) < len)
    483       1.1       scw 				printf("%02x: ", (u_int)i + 1);
    484       1.1       scw 		}
    485       1.1       scw 	}
    486       1.1       scw 
    487       1.1       scw 	while ((i++ % 16) != 0)
    488       1.1       scw 		printf("   ");
    489       1.1       scw 
    490       1.1       scw 	if (l < buf) {
    491       1.1       scw 		while (l < buf) {
    492       1.1       scw 			c = *l++;
    493       1.1       scw 			if (c < ' ' || c > 0x7e)
    494       1.1       scw 				c = '.';
    495       1.1       scw 			printf("%c", c);
    496       1.1       scw 		}
    497       1.1       scw 
    498       1.1       scw 		printf("\n");
    499       1.1       scw 	}
    500       1.1       scw }
    501       1.1       scw #endif
    502       1.1       scw 
    503       1.1       scw /*
    504       1.1       scw  * Very much like usbd_bulk_transfer(), except don't catch signals
    505       1.1       scw  */
    506       1.1       scw static void
    507       1.7  christos utoppy_bulk_transfer_cb(usbd_xfer_handle xfer,
    508       1.8  christos     usbd_private_handle priv,
    509       1.8  christos     usbd_status status)
    510       1.1       scw {
    511       1.1       scw 
    512       1.1       scw 	wakeup(xfer);
    513       1.1       scw }
    514       1.1       scw 
    515       1.1       scw static usbd_status
    516       1.1       scw utoppy_bulk_transfer(usbd_xfer_handle xfer, usbd_pipe_handle pipe,
    517       1.1       scw     u_int16_t flags, u_int32_t timeout, void *buf, u_int32_t *size,
    518       1.1       scw     const char *lbl)
    519       1.1       scw {
    520       1.1       scw 	usbd_status err;
    521       1.1       scw 	int s, error;
    522       1.1       scw 
    523       1.1       scw 	usbd_setup_xfer(xfer, pipe, 0, buf, *size, flags, timeout,
    524       1.1       scw 	    utoppy_bulk_transfer_cb);
    525       1.1       scw 	s = splusb();
    526       1.1       scw 	err = usbd_transfer(xfer);
    527       1.1       scw 	if (err != USBD_IN_PROGRESS) {
    528       1.1       scw 		splx(s);
    529       1.1       scw 		return (err);
    530       1.1       scw 	}
    531  1.8.10.3     itohy 	error = tsleep(xfer, PZERO, lbl, 0);
    532       1.1       scw 	splx(s);
    533       1.1       scw 	if (error) {
    534       1.1       scw 		usbd_abort_pipe(pipe);
    535       1.1       scw 		return (USBD_INTERRUPTED);
    536       1.1       scw 	}
    537       1.1       scw 	usbd_get_xfer_status(xfer, NULL, NULL, size, &err);
    538       1.1       scw 	return (err);
    539       1.1       scw }
    540       1.1       scw 
    541       1.1       scw static int
    542       1.1       scw utoppy_send_packet(struct utoppy_softc *sc, uint16_t cmd, uint32_t timeout)
    543       1.1       scw {
    544       1.1       scw 	struct utoppy_header *h;
    545       1.1       scw 	usbd_status err;
    546       1.1       scw 	uint32_t len;
    547       1.1       scw 	uint16_t dlen, crc;
    548       1.1       scw 	uint8_t *data, *e, t1, t2;
    549       1.1       scw 
    550       1.1       scw 	h = sc->sc_out_data;
    551       1.1       scw 
    552       1.1       scw 	DPRINTF(UTOPPY_DBG_SEND_PACKET, ("%s: utoppy_send_packet: cmd 0x%04x, "
    553       1.1       scw 	    "len %d\n", USBDEVNAME(sc->sc_dev), (u_int)cmd, h->h_len));
    554       1.1       scw 
    555       1.1       scw 	dlen = h->h_len;
    556       1.1       scw 	len = dlen + UTOPPY_HEADER_SIZE;
    557       1.1       scw 
    558       1.1       scw 	if (len & 1)
    559       1.1       scw 		len++;
    560       1.1       scw 	if ((len % 64) == 0)
    561       1.1       scw 		len += 2;
    562       1.1       scw 
    563       1.1       scw 	if (len >= UTOPPY_BSIZE) {
    564       1.1       scw 		DPRINTF(UTOPPY_DBG_SEND_PACKET, ("%s: utoppy_send_packet: "
    565       1.1       scw 		    "packet too big (%d)\n", USBDEVNAME(sc->sc_dev), (int)len));
    566       1.1       scw 		return (EINVAL);
    567       1.1       scw 	}
    568       1.1       scw 
    569       1.1       scw 	h->h_len = htole16(dlen + UTOPPY_HEADER_SIZE);
    570       1.1       scw 	h->h_cmd2 = 0;
    571       1.1       scw 	h->h_cmd = htole16(cmd);
    572       1.1       scw 
    573       1.1       scw 	/* The command word is part of the CRC */
    574       1.1       scw 	crc = UTOPPY_CRC16(0,   0);
    575       1.1       scw 	crc = UTOPPY_CRC16(crc, 0);
    576       1.1       scw 	crc = UTOPPY_CRC16(crc, cmd >> 8);
    577       1.1       scw 	crc = UTOPPY_CRC16(crc, cmd);
    578       1.1       scw 
    579       1.1       scw 	/*
    580       1.1       scw 	 * If there is data following the header, calculate the CRC and
    581       1.1       scw 	 * byte-swap as we go.
    582       1.1       scw 	 */
    583       1.1       scw 	if (dlen) {
    584       1.1       scw 		data = h->h_data;
    585       1.1       scw 		e = data + (dlen & ~1);
    586       1.1       scw 
    587       1.1       scw 		do {
    588       1.1       scw 			t1 = data[0];
    589       1.1       scw 			t2 = data[1];
    590       1.1       scw 			crc = UTOPPY_CRC16(crc, t1);
    591       1.1       scw 			crc = UTOPPY_CRC16(crc, t2);
    592       1.1       scw 			*data++ = t2;
    593       1.1       scw 			*data++ = t1;
    594       1.1       scw 		} while (data < e);
    595       1.1       scw 
    596       1.1       scw 		if (dlen & 1) {
    597       1.1       scw 			t1 = data[0];
    598       1.1       scw 			crc = UTOPPY_CRC16(crc, t1);
    599       1.1       scw 			data[1] = t1;
    600       1.1       scw 		}
    601       1.1       scw 	}
    602       1.1       scw 
    603       1.1       scw 	h->h_crc = htole16(crc);
    604       1.1       scw 	data = sc->sc_out_data;
    605       1.1       scw 
    606       1.1       scw 	DPRINTF(UTOPPY_DBG_SEND_PACKET, ("%s: utoppy_send_packet: total len "
    607       1.1       scw 	    "%d...\n", USBDEVNAME(sc->sc_dev), (int)len));
    608       1.1       scw 	DDUMP_PACKET(data, len);
    609       1.1       scw 
    610       1.1       scw 	do {
    611       1.1       scw 		uint32_t thislen;
    612       1.1       scw 
    613       1.1       scw 		thislen = min(len, UTOPPY_FRAG_SIZE);
    614       1.1       scw 
    615       1.1       scw 		memcpy(sc->sc_out_buf, data, thislen);
    616       1.1       scw 
    617       1.1       scw 		err = utoppy_bulk_transfer(sc->sc_out_xfer, sc->sc_out_pipe,
    618       1.1       scw 		    USBD_NO_COPY, timeout, sc->sc_out_buf, &thislen,
    619       1.1       scw 		    "utoppytx");
    620       1.1       scw 
    621       1.1       scw 		if (thislen != min(len, UTOPPY_FRAG_SIZE)) {
    622       1.1       scw 			DPRINTF(UTOPPY_DBG_SEND_PACKET, ("%s: "
    623       1.1       scw 			    "utoppy_send_packet: sent %ld, err %d\n",
    624       1.1       scw 			    USBDEVNAME(sc->sc_dev), (u_long)thislen, err));
    625       1.1       scw 		}
    626       1.1       scw 
    627       1.1       scw 		if (err == 0) {
    628       1.1       scw 			len -= thislen;
    629       1.1       scw 			data += thislen;
    630       1.1       scw 		}
    631       1.1       scw 	} while (err == 0 && len);
    632       1.1       scw 
    633       1.1       scw 	DPRINTF(UTOPPY_DBG_SEND_PACKET, ("%s: utoppy_send_packet: "
    634       1.1       scw 	    "usbd_bulk_transfer() returned %d.\n", USBDEVNAME(sc->sc_dev),err));
    635       1.1       scw 
    636       1.1       scw 	return (err ? utoppy_usbd_status2errno(err) : 0);
    637       1.1       scw }
    638       1.1       scw 
    639       1.1       scw static int
    640       1.1       scw utoppy_recv_packet(struct utoppy_softc *sc, uint16_t *respp, uint32_t timeout)
    641       1.1       scw {
    642       1.1       scw 	struct utoppy_header *h;
    643       1.1       scw 	usbd_status err;
    644       1.1       scw 	uint32_t len, thislen, requested, bytesleft;
    645       1.4       scw 	uint16_t crc;
    646       1.1       scw 	uint8_t *data, *e, t1, t2;
    647       1.1       scw 
    648       1.1       scw 	data = sc->sc_in_data;
    649       1.1       scw 	len = 0;
    650       1.1       scw 	bytesleft = UTOPPY_BSIZE;
    651       1.1       scw 
    652       1.1       scw 	DPRINTF(UTOPPY_DBG_RECV_PACKET, ("%s: utoppy_recv_packet: ...\n",
    653       1.1       scw 	    USBDEVNAME(sc->sc_dev)));
    654       1.1       scw 
    655       1.1       scw 	do {
    656       1.1       scw 		requested = thislen = min(bytesleft, UTOPPY_FRAG_SIZE);
    657       1.1       scw 
    658       1.1       scw 		err = utoppy_bulk_transfer(sc->sc_in_xfer, sc->sc_in_pipe,
    659       1.1       scw 		    USBD_NO_COPY | USBD_SHORT_XFER_OK, timeout, sc->sc_in_buf,
    660       1.1       scw 		    &thislen, "utoppyrx");
    661       1.1       scw 
    662       1.1       scw 		DPRINTF(UTOPPY_DBG_RECV_PACKET, ("%s: utoppy_recv_packet: "
    663       1.1       scw 		    "usbd_bulk_transfer() returned %d, thislen %d, data %p\n",
    664       1.1       scw 		    USBDEVNAME(sc->sc_dev), err, (u_int)thislen, data));
    665       1.1       scw 
    666       1.1       scw 		if (err == 0) {
    667       1.1       scw 			memcpy(data, sc->sc_in_buf, thislen);
    668       1.1       scw 			DDUMP_PACKET(data, thislen);
    669       1.1       scw 			len += thislen;
    670       1.1       scw 			bytesleft -= thislen;
    671       1.1       scw 			data += thislen;
    672       1.1       scw 		}
    673       1.1       scw 	} while (err == 0 && bytesleft && thislen == requested);
    674       1.1       scw 
    675       1.1       scw 	if (err)
    676       1.1       scw 		return (utoppy_usbd_status2errno(err));
    677       1.1       scw 
    678       1.1       scw 	h = sc->sc_in_data;
    679       1.1       scw 
    680       1.1       scw 	DPRINTF(UTOPPY_DBG_RECV_PACKET, ("%s: utoppy_recv_packet: received %d "
    681       1.1       scw 	    "bytes in total to %p\n", USBDEVNAME(sc->sc_dev), (u_int)len, h));
    682       1.1       scw 	DDUMP_PACKET(h, len);
    683       1.1       scw 
    684       1.1       scw 	if (len < UTOPPY_HEADER_SIZE || len < (uint32_t)le16toh(h->h_len)) {
    685       1.1       scw 		DPRINTF(UTOPPY_DBG_RECV_PACKET, ("%s: utoppy_recv_packet: bad "
    686       1.1       scw 		    " length (len %d, h_len %d)\n", USBDEVNAME(sc->sc_dev),
    687       1.1       scw 		    (int)len, le16toh(h->h_len)));
    688       1.1       scw 		return (EIO);
    689       1.1       scw 	}
    690       1.1       scw 
    691       1.1       scw 	len = h->h_len = le16toh(h->h_len);
    692       1.1       scw 	h->h_crc = le16toh(h->h_crc);
    693       1.1       scw 	*respp = h->h_cmd = le16toh(h->h_cmd);
    694       1.1       scw 	h->h_cmd2 = le16toh(h->h_cmd2);
    695       1.1       scw 
    696       1.1       scw 	/*
    697       1.1       scw 	 * To maximise data throughput when transferring files, acknowledge
    698       1.1       scw 	 * data blocks as soon as we receive them. If we detect an error
    699       1.1       scw 	 * later on, we can always cancel.
    700       1.1       scw 	 */
    701       1.1       scw 	if (*respp == UTOPPY_RESP_FILE_DATA) {
    702       1.1       scw 		DPRINTF(UTOPPY_DBG_RECV_PACKET, ("%s: utoppy_recv_packet: "
    703       1.1       scw 		    "ACKing file data\n", USBDEVNAME(sc->sc_dev)));
    704       1.1       scw 
    705       1.1       scw 		UTOPPY_OUT_INIT(sc);
    706       1.1       scw 		err = utoppy_send_packet(sc, UTOPPY_CMD_ACK,
    707       1.1       scw 		    UTOPPY_SHORT_TIMEOUT);
    708       1.1       scw 		if (err) {
    709       1.1       scw 			DPRINTF(UTOPPY_DBG_RECV_PACKET, ("%s: "
    710       1.1       scw 			    "utoppy_recv_packet: failed to ACK file data: %d\n",
    711       1.1       scw 			    USBDEVNAME(sc->sc_dev), err));
    712       1.1       scw 			return (err);
    713       1.1       scw 		}
    714       1.1       scw 	}
    715       1.1       scw 
    716       1.1       scw 	/* The command word is part of the CRC */
    717       1.4       scw 	crc = UTOPPY_CRC16(0,   h->h_cmd2 >> 8);
    718       1.4       scw 	crc = UTOPPY_CRC16(crc, h->h_cmd2);
    719       1.1       scw 	crc = UTOPPY_CRC16(crc, h->h_cmd >> 8);
    720       1.1       scw 	crc = UTOPPY_CRC16(crc, h->h_cmd);
    721       1.1       scw 
    722       1.1       scw 	/*
    723       1.1       scw 	 * Extract any payload, byte-swapping and calculating the CRC16
    724       1.1       scw 	 * as we go.
    725       1.1       scw 	 */
    726       1.1       scw 	if (len > UTOPPY_HEADER_SIZE) {
    727       1.1       scw 		data = h->h_data;
    728       1.1       scw 		e = data + ((len & ~1) - UTOPPY_HEADER_SIZE);
    729       1.1       scw 
    730       1.1       scw 		while (data < e) {
    731       1.1       scw 			t1 = data[0];
    732       1.1       scw 			t2 = data[1];
    733       1.1       scw 			crc = UTOPPY_CRC16(crc, t2);
    734       1.1       scw 			crc = UTOPPY_CRC16(crc, t1);
    735       1.1       scw 			*data++ = t2;
    736       1.1       scw 			*data++ = t1;
    737       1.1       scw 		}
    738       1.1       scw 
    739       1.1       scw 		if (len & 1) {
    740       1.1       scw 			t1 = data[1];
    741       1.1       scw 			crc = UTOPPY_CRC16(crc, t1);
    742       1.1       scw 			*data = t1;
    743       1.1       scw 		}
    744       1.1       scw 	}
    745       1.1       scw 
    746       1.1       scw 	sc->sc_in_len = (size_t) len - UTOPPY_HEADER_SIZE;
    747       1.1       scw 	sc->sc_in_offset = 0;
    748       1.1       scw 
    749       1.1       scw 	DPRINTF(UTOPPY_DBG_RECV_PACKET, ("%s: utoppy_recv_packet: len %d, "
    750       1.1       scw 	    "crc 0x%04x, hdrcrc 0x%04x\n", USBDEVNAME(sc->sc_dev),
    751       1.1       scw 	    (int)len, crc, h->h_crc));
    752       1.1       scw 	DDUMP_PACKET(h, len);
    753       1.1       scw 
    754       1.1       scw 	return ((crc == h->h_crc) ? 0 : EBADMSG);
    755       1.1       scw }
    756       1.1       scw 
    757       1.1       scw static __inline void *
    758       1.1       scw utoppy_current_ptr(void *b)
    759       1.1       scw {
    760       1.1       scw 	struct utoppy_header *h = b;
    761       1.1       scw 
    762       1.1       scw 	return (&h->h_data[h->h_len]);
    763       1.1       scw }
    764       1.1       scw 
    765       1.1       scw static __inline void
    766       1.1       scw utoppy_advance_ptr(void *b, size_t len)
    767       1.1       scw {
    768       1.1       scw 	struct utoppy_header *h = b;
    769       1.1       scw 
    770       1.1       scw 	h->h_len += len;
    771       1.1       scw }
    772       1.1       scw 
    773       1.1       scw static __inline void
    774       1.1       scw utoppy_add_8(struct utoppy_softc *sc, uint8_t v)
    775       1.1       scw {
    776       1.1       scw 	struct utoppy_header *h = sc->sc_out_data;
    777       1.1       scw 	uint8_t *p;
    778       1.1       scw 
    779       1.1       scw 	p = utoppy_current_ptr(h);
    780       1.1       scw 	*p = v;
    781       1.1       scw 	utoppy_advance_ptr(h, sizeof(v));
    782       1.1       scw }
    783       1.1       scw 
    784       1.1       scw static __inline void
    785       1.1       scw utoppy_add_16(struct utoppy_softc *sc, uint16_t v)
    786       1.1       scw {
    787       1.1       scw 	struct utoppy_header *h = sc->sc_out_data;
    788       1.1       scw 	uint8_t *p;
    789       1.1       scw 
    790       1.1       scw 	p = utoppy_current_ptr(h);
    791       1.1       scw 	*p++ = (uint8_t)(v >> 8);
    792       1.1       scw 	*p = (uint8_t)v;
    793       1.1       scw 	utoppy_advance_ptr(h, sizeof(v));
    794       1.1       scw }
    795       1.1       scw 
    796       1.1       scw static __inline void
    797       1.1       scw utoppy_add_32(struct utoppy_softc *sc, uint32_t v)
    798       1.1       scw {
    799       1.1       scw 	struct utoppy_header *h = sc->sc_out_data;
    800       1.1       scw 	uint8_t *p;
    801       1.1       scw 
    802       1.1       scw 	p = utoppy_current_ptr(h);
    803       1.1       scw 	*p++ = (uint8_t)(v >> 24);
    804       1.1       scw 	*p++ = (uint8_t)(v >> 16);
    805       1.1       scw 	*p++ = (uint8_t)(v >> 8);
    806       1.1       scw 	*p = (uint8_t)v;
    807       1.1       scw 	utoppy_advance_ptr(h, sizeof(v));
    808       1.1       scw }
    809       1.1       scw 
    810       1.1       scw static __inline void
    811       1.1       scw utoppy_add_64(struct utoppy_softc *sc, uint64_t v)
    812       1.1       scw {
    813       1.1       scw 	struct utoppy_header *h = sc->sc_out_data;
    814       1.1       scw 	uint8_t *p;
    815       1.1       scw 
    816       1.1       scw 	p = utoppy_current_ptr(h);
    817       1.1       scw 	*p++ = (uint8_t)(v >> 56);
    818       1.1       scw 	*p++ = (uint8_t)(v >> 48);
    819       1.1       scw 	*p++ = (uint8_t)(v >> 40);
    820       1.1       scw 	*p++ = (uint8_t)(v >> 32);
    821       1.1       scw 	*p++ = (uint8_t)(v >> 24);
    822       1.1       scw 	*p++ = (uint8_t)(v >> 16);
    823       1.1       scw 	*p++ = (uint8_t)(v >> 8);
    824       1.1       scw 	*p = (uint8_t)v;
    825       1.1       scw 	utoppy_advance_ptr(h, sizeof(v));
    826       1.1       scw }
    827       1.1       scw 
    828       1.1       scw static __inline void
    829       1.1       scw utoppy_add_string(struct utoppy_softc *sc, const char *str, size_t len)
    830       1.1       scw {
    831       1.1       scw 	struct utoppy_header *h = sc->sc_out_data;
    832       1.1       scw 	char *p;
    833       1.1       scw 
    834       1.1       scw 	p = utoppy_current_ptr(h);
    835       1.1       scw 	memset(p, 0, len);
    836       1.1       scw 	strncpy(p, str, len);
    837       1.1       scw 	utoppy_advance_ptr(h, len);
    838       1.1       scw }
    839       1.1       scw 
    840       1.1       scw static int
    841       1.1       scw utoppy_add_path(struct utoppy_softc *sc, const char *path, int putlen)
    842       1.1       scw {
    843       1.1       scw 	struct utoppy_header *h = sc->sc_out_data;
    844       1.1       scw 	uint8_t *p, *str, *s;
    845       1.1       scw 	size_t len;
    846       1.1       scw 	int err;
    847       1.1       scw 
    848       1.1       scw 	p = utoppy_current_ptr(h);
    849       1.1       scw 
    850       1.1       scw 	str = putlen ? (p + sizeof(uint16_t)) : p;
    851       1.1       scw 
    852       1.1       scw 	err = copyinstr(path, str, UTOPPY_MAX_FILENAME_LEN, &len);
    853       1.1       scw 
    854       1.1       scw 	DPRINTF(UTOPPY_DBG_ADDPATH, ("utoppy_add_path: err %d, len %d\n",
    855       1.1       scw 	    err, (int)len));
    856       1.1       scw 
    857       1.1       scw 	if (err)
    858       1.1       scw 		return (err);
    859       1.1       scw 
    860       1.1       scw 	if (len < 2)
    861       1.1       scw 		return (EINVAL);
    862       1.1       scw 
    863       1.1       scw 	/*
    864       1.1       scw 	 * copyinstr(9) has already copied the terminating NUL character,
    865       1.1       scw 	 * but we append another one in case we have to pad the length
    866       1.1       scw 	 * later on.
    867       1.1       scw 	 */
    868       1.1       scw 	str[len] = '\0';
    869       1.1       scw 
    870       1.1       scw 	/*
    871       1.1       scw 	 * The Toppy uses backslash as the directory separator, so convert
    872       1.1       scw 	 * all forward slashes.
    873       1.1       scw 	 */
    874       1.1       scw 	for (s = &str[len - 2]; s >= str; s--)
    875       1.1       scw 		if (*s == '/')
    876       1.1       scw 			*s = '\\';
    877       1.1       scw 
    878       1.1       scw 	if ((len + h->h_len) & 1)
    879       1.1       scw 		len++;
    880       1.1       scw 
    881       1.1       scw 	if (putlen)
    882       1.1       scw 		utoppy_add_16(sc, len);
    883       1.1       scw 
    884       1.1       scw 	utoppy_advance_ptr(h, len);
    885       1.1       scw 
    886       1.1       scw 	DPRINTF(UTOPPY_DBG_ADDPATH, ("utoppy_add_path: final len %d\n",
    887       1.1       scw 	    (u_int)len));
    888       1.1       scw 
    889       1.1       scw 	return (0);
    890       1.1       scw }
    891       1.1       scw 
    892       1.1       scw static __inline int
    893       1.1       scw utoppy_get_8(struct utoppy_softc *sc, uint8_t *vp)
    894       1.1       scw {
    895       1.1       scw 	uint8_t *p;
    896       1.1       scw 
    897       1.1       scw 	if (sc->sc_in_len < sizeof(*vp))
    898       1.1       scw 		return (1);
    899       1.1       scw 
    900       1.1       scw 	p = UTOPPY_IN_DATA(sc);
    901       1.1       scw 	*vp = *p;
    902       1.1       scw 	sc->sc_in_offset += sizeof(*vp);
    903       1.1       scw 	sc->sc_in_len -= sizeof(*vp);
    904       1.1       scw 	return (0);
    905       1.1       scw }
    906       1.1       scw 
    907       1.1       scw static __inline int
    908       1.1       scw utoppy_get_16(struct utoppy_softc *sc, uint16_t *vp)
    909       1.1       scw {
    910       1.1       scw 	uint16_t v;
    911       1.1       scw 	uint8_t *p;
    912       1.1       scw 
    913       1.1       scw 	if (sc->sc_in_len < sizeof(v))
    914       1.1       scw 		return (1);
    915       1.1       scw 
    916       1.1       scw 	p = UTOPPY_IN_DATA(sc);
    917       1.1       scw 	v = *p++;
    918       1.1       scw 	v = (v << 8) | *p;
    919       1.1       scw 	*vp = v;
    920       1.1       scw 	sc->sc_in_offset += sizeof(v);
    921       1.1       scw 	sc->sc_in_len -= sizeof(v);
    922       1.1       scw 	return (0);
    923       1.1       scw }
    924       1.1       scw 
    925       1.1       scw static __inline int
    926       1.1       scw utoppy_get_32(struct utoppy_softc *sc, uint32_t *vp)
    927       1.1       scw {
    928       1.1       scw 	uint32_t v;
    929       1.1       scw 	uint8_t *p;
    930       1.1       scw 
    931       1.1       scw 	if (sc->sc_in_len < sizeof(v))
    932       1.1       scw 		return (1);
    933       1.1       scw 
    934       1.1       scw 	p = UTOPPY_IN_DATA(sc);
    935       1.1       scw 	v = *p++;
    936       1.1       scw 	v = (v << 8) | *p++;
    937       1.1       scw 	v = (v << 8) | *p++;
    938       1.1       scw 	v = (v << 8) | *p;
    939       1.1       scw 	*vp = v;
    940       1.1       scw 	sc->sc_in_offset += sizeof(v);
    941       1.1       scw 	sc->sc_in_len -= sizeof(v);
    942       1.1       scw 	return (0);
    943       1.1       scw }
    944       1.1       scw 
    945       1.1       scw static __inline int
    946       1.1       scw utoppy_get_64(struct utoppy_softc *sc, uint64_t *vp)
    947       1.1       scw {
    948       1.1       scw 	uint64_t v;
    949       1.1       scw 	uint8_t *p;
    950       1.1       scw 
    951       1.1       scw 	if (sc->sc_in_len < sizeof(v))
    952       1.1       scw 		return (1);
    953       1.1       scw 
    954       1.1       scw 	p = UTOPPY_IN_DATA(sc);
    955       1.1       scw 	v = *p++;
    956       1.1       scw 	v = (v << 8) | *p++;
    957       1.1       scw 	v = (v << 8) | *p++;
    958       1.1       scw 	v = (v << 8) | *p++;
    959       1.1       scw 	v = (v << 8) | *p++;
    960       1.1       scw 	v = (v << 8) | *p++;
    961       1.1       scw 	v = (v << 8) | *p++;
    962       1.1       scw 	v = (v << 8) | *p;
    963       1.1       scw 	*vp = v;
    964       1.1       scw 	sc->sc_in_offset += sizeof(v);
    965       1.1       scw 	sc->sc_in_len -= sizeof(v);
    966       1.1       scw 	return (0);
    967       1.1       scw }
    968       1.1       scw 
    969       1.1       scw static __inline int
    970       1.1       scw utoppy_get_string(struct utoppy_softc *sc, char *str, size_t len)
    971       1.1       scw {
    972       1.1       scw 	char *p;
    973       1.1       scw 
    974       1.1       scw 	if (sc->sc_in_len < len)
    975       1.1       scw 		return (1);
    976       1.1       scw 
    977       1.1       scw 	memset(str, 0, len);
    978       1.1       scw 	p = UTOPPY_IN_DATA(sc);
    979       1.1       scw 	strncpy(str, p, len);
    980       1.1       scw 	sc->sc_in_offset += len;
    981       1.1       scw 	sc->sc_in_len -= len;
    982       1.1       scw 	return (0);
    983       1.1       scw }
    984       1.1       scw 
    985       1.1       scw static int
    986       1.1       scw utoppy_command(struct utoppy_softc *sc, uint16_t cmd, int timeout,
    987       1.1       scw     uint16_t *presp)
    988       1.1       scw {
    989       1.1       scw 	int err;
    990       1.1       scw 
    991       1.1       scw 	err = utoppy_send_packet(sc, cmd, timeout);
    992       1.1       scw 	if (err)
    993       1.1       scw 		return (err);
    994       1.1       scw 
    995       1.1       scw 	err = utoppy_recv_packet(sc, presp, timeout);
    996       1.1       scw 	if (err == EBADMSG) {
    997       1.1       scw 		UTOPPY_OUT_INIT(sc);
    998       1.1       scw 		utoppy_send_packet(sc, UTOPPY_RESP_ERROR, timeout);
    999       1.1       scw 	}
   1000       1.1       scw 
   1001       1.1       scw 	return (err);
   1002       1.1       scw }
   1003       1.1       scw 
   1004       1.1       scw static int
   1005       1.1       scw utoppy_timestamp_decode(struct utoppy_softc *sc, time_t *tp)
   1006       1.1       scw {
   1007       1.1       scw 	uint16_t mjd;
   1008       1.1       scw 	uint8_t hour, minute, sec;
   1009       1.1       scw 	uint32_t rv;
   1010       1.1       scw 
   1011       1.1       scw 	if (utoppy_get_16(sc, &mjd) || utoppy_get_8(sc, &hour) ||
   1012       1.1       scw 	    utoppy_get_8(sc, &minute) || utoppy_get_8(sc, &sec))
   1013       1.1       scw 		return (1);
   1014       1.1       scw 
   1015       1.1       scw 	if (mjd == 0xffffu && hour == 0xffu && minute == 0xffu && sec == 0xffu){
   1016       1.1       scw 		*tp = 0;
   1017       1.1       scw 		return (0);
   1018       1.1       scw 	}
   1019       1.1       scw 
   1020       1.1       scw 	rv = (mjd < UTOPPY_MJD_1970) ? UTOPPY_MJD_1970 : (uint32_t) mjd;
   1021       1.1       scw 
   1022       1.1       scw 	/* Calculate seconds since 1970 */
   1023       1.1       scw 	rv = (rv - UTOPPY_MJD_1970) * 60 * 60 * 24;
   1024       1.1       scw 
   1025       1.1       scw 	/* Add in the hours, minutes, and seconds */
   1026       1.1       scw 	rv += (uint32_t)hour * 60 * 60;
   1027       1.1       scw 	rv += (uint32_t)minute * 60;
   1028       1.1       scw 	rv += sec;
   1029       1.1       scw 	*tp = (time_t)rv;
   1030       1.1       scw 
   1031       1.1       scw 	return (0);
   1032       1.1       scw }
   1033       1.1       scw 
   1034       1.1       scw static void
   1035       1.1       scw utoppy_timestamp_encode(struct utoppy_softc *sc, time_t t)
   1036       1.1       scw {
   1037       1.1       scw 	u_int mjd, hour, minute;
   1038       1.1       scw 
   1039       1.1       scw 	mjd = t / (60 * 60 * 24);
   1040       1.1       scw 	t -= mjd * 60 * 60 * 24;
   1041       1.1       scw 
   1042       1.1       scw 	hour = t / (60 * 60);
   1043       1.1       scw 	t -= hour * 60 * 60;
   1044       1.1       scw 
   1045       1.1       scw 	minute = t / 60;
   1046       1.1       scw 	t -= minute * 60;
   1047       1.1       scw 
   1048       1.1       scw 	utoppy_add_16(sc, mjd + UTOPPY_MJD_1970);
   1049       1.1       scw 	utoppy_add_8(sc, hour);
   1050       1.1       scw 	utoppy_add_8(sc, minute);
   1051       1.1       scw 	utoppy_add_8(sc, t);
   1052       1.1       scw }
   1053       1.1       scw 
   1054       1.1       scw static int
   1055       1.1       scw utoppy_turbo_mode(struct utoppy_softc *sc, int state)
   1056       1.1       scw {
   1057       1.1       scw 	uint16_t r;
   1058       1.1       scw 	int err;
   1059       1.1       scw 
   1060       1.1       scw 	UTOPPY_OUT_INIT(sc);
   1061       1.1       scw 	utoppy_add_32(sc, state);
   1062       1.1       scw 
   1063       1.1       scw 	err = utoppy_command(sc, UTOPPY_CMD_TURBO, UTOPPY_SHORT_TIMEOUT, &r);
   1064       1.1       scw 	if (err)
   1065       1.1       scw 		return (err);
   1066       1.1       scw 
   1067       1.1       scw 	return ((r == UTOPPY_RESP_SUCCESS) ? 0 : EIO);
   1068       1.1       scw }
   1069       1.1       scw 
   1070       1.1       scw static int
   1071       1.1       scw utoppy_check_ready(struct utoppy_softc *sc)
   1072       1.1       scw {
   1073       1.1       scw 	uint16_t r;
   1074       1.1       scw 	int err;
   1075       1.1       scw 
   1076       1.1       scw 	UTOPPY_OUT_INIT(sc);
   1077       1.1       scw 
   1078       1.1       scw 	err = utoppy_command(sc, UTOPPY_CMD_READY, UTOPPY_LONG_TIMEOUT, &r);
   1079       1.1       scw 	if (err)
   1080       1.1       scw 		return (err);
   1081       1.1       scw 
   1082       1.1       scw 	return ((r == UTOPPY_RESP_SUCCESS) ? 0 : EIO);
   1083       1.1       scw }
   1084       1.1       scw 
   1085       1.1       scw static int
   1086       1.1       scw utoppy_cancel(struct utoppy_softc *sc)
   1087       1.1       scw {
   1088       1.1       scw 	uint16_t r;
   1089       1.1       scw 	int err, i;
   1090       1.1       scw 
   1091       1.1       scw 	/*
   1092       1.1       scw 	 * Issue the cancel command serveral times. the Toppy doesn't
   1093       1.1       scw 	 * always respond to the first.
   1094       1.1       scw 	 */
   1095       1.1       scw 	for (i = 0; i < 3; i++) {
   1096       1.1       scw 		UTOPPY_OUT_INIT(sc);
   1097       1.1       scw 		err = utoppy_command(sc, UTOPPY_CMD_CANCEL,
   1098       1.1       scw 		    UTOPPY_SHORT_TIMEOUT, &r);
   1099       1.1       scw 		if (err == 0 && r == UTOPPY_RESP_SUCCESS)
   1100       1.1       scw 			break;
   1101       1.1       scw 		err = ETIMEDOUT;
   1102       1.1       scw 	}
   1103       1.1       scw 
   1104       1.1       scw 	if (err)
   1105       1.1       scw 		return (err);
   1106       1.1       scw 
   1107       1.1       scw 	/*
   1108       1.1       scw 	 * Make sure turbo mode is off, otherwise the Toppy will not
   1109       1.1       scw 	 * respond to remote control input.
   1110       1.1       scw 	 */
   1111       1.1       scw 	(void) utoppy_turbo_mode(sc, 0);
   1112       1.1       scw 
   1113       1.1       scw 	sc->sc_state = UTOPPY_STATE_IDLE;
   1114       1.1       scw 	return (0);
   1115       1.1       scw }
   1116       1.1       scw 
   1117       1.1       scw static int
   1118       1.1       scw utoppy_stats(struct utoppy_softc *sc, struct utoppy_stats *us)
   1119       1.1       scw {
   1120       1.1       scw 	uint32_t hsize, hfree;
   1121       1.1       scw 	uint16_t r;
   1122       1.1       scw 	int err;
   1123       1.1       scw 
   1124       1.1       scw 	UTOPPY_OUT_INIT(sc);
   1125       1.1       scw 	err = utoppy_command(sc, UTOPPY_CMD_STATS, UTOPPY_LONG_TIMEOUT, &r);
   1126       1.1       scw 	if (err)
   1127       1.1       scw 		return (err);
   1128       1.1       scw 
   1129       1.1       scw 	if (r != UTOPPY_RESP_STATS_DATA)
   1130       1.1       scw 		return (EIO);
   1131       1.1       scw 
   1132       1.1       scw 	if (utoppy_get_32(sc, &hsize) || utoppy_get_32(sc, &hfree))
   1133       1.1       scw 		return (EIO);
   1134       1.1       scw 
   1135       1.1       scw 	us->us_hdd_size = hsize;
   1136       1.1       scw 	us->us_hdd_size *= 1024;
   1137       1.1       scw 	us->us_hdd_free = hfree;
   1138       1.1       scw 	us->us_hdd_free *= 1024;
   1139       1.1       scw 
   1140       1.1       scw 	return (0);
   1141       1.1       scw }
   1142       1.1       scw 
   1143       1.1       scw static int
   1144       1.1       scw utoppy_readdir_next(struct utoppy_softc *sc)
   1145       1.1       scw {
   1146       1.1       scw 	uint16_t resp;
   1147       1.1       scw 	int err;
   1148       1.1       scw 
   1149       1.1       scw 	DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppy_readdir_next: running...\n",
   1150       1.1       scw 	    USBDEVNAME(sc->sc_dev)));
   1151       1.1       scw 
   1152       1.1       scw 	/*
   1153       1.1       scw 	 * Fetch the next READDIR response
   1154       1.1       scw 	 */
   1155       1.1       scw 	err = utoppy_recv_packet(sc, &resp, UTOPPY_LONG_TIMEOUT);
   1156       1.1       scw 	if (err) {
   1157       1.1       scw 		DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppy_readdir_next: "
   1158       1.1       scw 		    "utoppy_recv_packet() returned %d\n",
   1159       1.1       scw 		    USBDEVNAME(sc->sc_dev), err));
   1160       1.1       scw 		if (err == EBADMSG) {
   1161       1.1       scw 			UTOPPY_OUT_INIT(sc);
   1162       1.1       scw 			utoppy_send_packet(sc, UTOPPY_RESP_ERROR,
   1163       1.1       scw 			    UTOPPY_LONG_TIMEOUT);
   1164       1.1       scw 		}
   1165       1.1       scw 		utoppy_cancel(sc);
   1166       1.1       scw 		return (err);
   1167       1.1       scw 	}
   1168       1.1       scw 
   1169       1.1       scw 	DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppy_readdir_next: "
   1170       1.1       scw 	    "utoppy_recv_packet() returned %d, len %ld\n",
   1171       1.1       scw 	    USBDEVNAME(sc->sc_dev), err, (u_long)sc->sc_in_len));
   1172       1.1       scw 
   1173       1.1       scw 	switch (resp) {
   1174       1.1       scw 	case UTOPPY_RESP_READDIR_DATA:
   1175       1.1       scw 		DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppy_readdir_next: "
   1176       1.1       scw 		    "UTOPPY_RESP_READDIR_DATA\n", USBDEVNAME(sc->sc_dev)));
   1177       1.1       scw 
   1178       1.1       scw 		UTOPPY_OUT_INIT(sc);
   1179       1.1       scw 		err = utoppy_send_packet(sc, UTOPPY_CMD_ACK,
   1180       1.1       scw 		    UTOPPY_LONG_TIMEOUT);
   1181       1.1       scw 		if (err) {
   1182       1.1       scw 			DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppy_readdir_next: "
   1183       1.1       scw 			    "utoppy_send_packet(ACK) returned %d\n",
   1184       1.1       scw 			    USBDEVNAME(sc->sc_dev), err));
   1185       1.1       scw 			utoppy_cancel(sc);
   1186       1.1       scw 			return (err);
   1187       1.1       scw 		}
   1188       1.1       scw 		sc->sc_state = UTOPPY_STATE_READDIR;
   1189       1.1       scw 		sc->sc_in_offset = 0;
   1190       1.1       scw 		break;
   1191       1.1       scw 
   1192       1.1       scw 	case UTOPPY_RESP_READDIR_END:
   1193       1.1       scw 		DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppy_readdir_next: "
   1194       1.1       scw 		    "UTOPPY_RESP_READDIR_END\n", USBDEVNAME(sc->sc_dev)));
   1195       1.1       scw 
   1196       1.1       scw 		UTOPPY_OUT_INIT(sc);
   1197       1.1       scw 		utoppy_send_packet(sc, UTOPPY_CMD_ACK, UTOPPY_SHORT_TIMEOUT);
   1198       1.1       scw 		sc->sc_state = UTOPPY_STATE_IDLE;
   1199       1.1       scw 		sc->sc_in_len = 0;
   1200       1.1       scw 		break;
   1201       1.1       scw 
   1202       1.1       scw 	default:
   1203       1.1       scw 		DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppy_readdir_next: "
   1204       1.1       scw 		    "bad response: 0x%x\n", USBDEVNAME(sc->sc_dev), resp));
   1205       1.1       scw 		sc->sc_state = UTOPPY_STATE_IDLE;
   1206       1.1       scw 		sc->sc_in_len = 0;
   1207       1.1       scw 		return (EIO);
   1208       1.1       scw 	}
   1209       1.1       scw 
   1210       1.1       scw 	return (0);
   1211       1.1       scw }
   1212       1.1       scw 
   1213       1.1       scw static size_t
   1214       1.1       scw utoppy_readdir_decode(struct utoppy_softc *sc, struct utoppy_dirent *ud)
   1215       1.1       scw {
   1216       1.1       scw 	uint8_t ftype;
   1217       1.1       scw 
   1218       1.1       scw 	DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppy_readdir_decode: bytes left"
   1219       1.1       scw 	    " %d\n", USBDEVNAME(sc->sc_dev), (int)sc->sc_in_len));
   1220       1.1       scw 
   1221       1.1       scw 	if (utoppy_timestamp_decode(sc, &ud->ud_mtime) ||
   1222       1.1       scw 	    utoppy_get_8(sc, &ftype) || utoppy_get_64(sc, &ud->ud_size) ||
   1223       1.1       scw 	    utoppy_get_string(sc, ud->ud_path, UTOPPY_MAX_FILENAME_LEN + 1) ||
   1224       1.1       scw 	    utoppy_get_32(sc, &ud->ud_attributes)) {
   1225       1.1       scw 		DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppy_readdir_decode: no "
   1226       1.1       scw 		    "more to decode\n", USBDEVNAME(sc->sc_dev)));
   1227       1.1       scw 		return (0);
   1228       1.1       scw 	}
   1229       1.1       scw 
   1230       1.1       scw 	switch (ftype) {
   1231       1.1       scw 	case UTOPPY_FTYPE_DIR:
   1232       1.1       scw 		ud->ud_type = UTOPPY_DIRENT_DIRECTORY;
   1233       1.1       scw 		break;
   1234       1.1       scw 	case UTOPPY_FTYPE_FILE:
   1235       1.1       scw 		ud->ud_type = UTOPPY_DIRENT_FILE;
   1236       1.1       scw 		break;
   1237       1.1       scw 	default:
   1238       1.1       scw 		ud->ud_type = UTOPPY_DIRENT_UNKNOWN;
   1239       1.1       scw 		break;
   1240       1.1       scw 	}
   1241       1.1       scw 
   1242       1.1       scw 	DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppy_readdir_decode: %s '%s', "
   1243       1.1       scw 	    "size %lld, time 0x%08lx, attr 0x%08x\n", USBDEVNAME(sc->sc_dev),
   1244       1.1       scw 	    (ftype == UTOPPY_FTYPE_DIR) ? "DIR" :
   1245       1.1       scw 	    ((ftype == UTOPPY_FTYPE_FILE) ? "FILE" : "UNKNOWN"), ud->ud_path,
   1246       1.1       scw 	    ud->ud_size, (u_long)ud->ud_mtime, ud->ud_attributes));
   1247       1.1       scw 
   1248       1.1       scw 	return (1);
   1249       1.1       scw }
   1250       1.1       scw 
   1251       1.1       scw static int
   1252       1.1       scw utoppy_readfile_next(struct utoppy_softc *sc)
   1253       1.1       scw {
   1254       1.1       scw 	uint64_t off;
   1255       1.1       scw 	uint16_t resp;
   1256       1.1       scw 	int err;
   1257       1.1       scw 
   1258       1.1       scw 	err = utoppy_recv_packet(sc, &resp, UTOPPY_LONG_TIMEOUT);
   1259       1.1       scw 	if (err) {
   1260       1.1       scw 		DPRINTF(UTOPPY_DBG_READ, ("%s: utoppy_readfile_next: "
   1261       1.1       scw 		    "utoppy_recv_packet() returned %d\n",
   1262       1.1       scw 		    USBDEVNAME(sc->sc_dev), err));
   1263       1.1       scw 		utoppy_cancel(sc);
   1264       1.1       scw 		return (err);
   1265       1.1       scw 	}
   1266       1.1       scw 
   1267       1.1       scw 	switch (resp) {
   1268       1.1       scw 	case UTOPPY_RESP_FILE_HEADER:
   1269       1.1       scw 		/* ACK it */
   1270       1.1       scw 		UTOPPY_OUT_INIT(sc);
   1271       1.1       scw 		err = utoppy_send_packet(sc, UTOPPY_CMD_ACK,
   1272       1.1       scw 		    UTOPPY_LONG_TIMEOUT);
   1273       1.1       scw 		if (err) {
   1274       1.1       scw 			DPRINTF(UTOPPY_DBG_READ, ("%s: utoppy_readfile_next: "
   1275       1.1       scw 			    "utoppy_send_packet(UTOPPY_CMD_ACK) returned %d\n",
   1276       1.1       scw 			    USBDEVNAME(sc->sc_dev), err));
   1277       1.1       scw 			utoppy_cancel(sc);
   1278       1.1       scw 			return (err);
   1279       1.1       scw 		}
   1280       1.1       scw 
   1281       1.1       scw 		sc->sc_in_len = 0;
   1282       1.1       scw 		DPRINTF(UTOPPY_DBG_READ, ("%s: utoppy_readfile_next: "
   1283       1.1       scw 		    "FILE_HEADER done\n", USBDEVNAME(sc->sc_dev)));
   1284       1.1       scw 		break;
   1285       1.1       scw 
   1286       1.1       scw 	case UTOPPY_RESP_FILE_DATA:
   1287       1.1       scw 		/* Already ACK'd */
   1288       1.1       scw 		if (utoppy_get_64(sc, &off)) {
   1289       1.1       scw 			DPRINTF(UTOPPY_DBG_READ, ("%s: utoppy_readfile_next: "
   1290       1.1       scw 			    "UTOPPY_RESP_FILE_DATA did not provide offset\n",
   1291       1.1       scw 			    USBDEVNAME(sc->sc_dev)));
   1292       1.1       scw 			utoppy_cancel(sc);
   1293       1.1       scw 			return (EBADMSG);
   1294       1.1       scw 		}
   1295       1.1       scw 
   1296       1.1       scw 		DPRINTF(UTOPPY_DBG_READ, ("%s: utoppy_readfile_next: "
   1297       1.1       scw 		    "UTOPPY_RESP_FILE_DATA: offset %lld, bytes left %ld\n",
   1298       1.1       scw 		    USBDEVNAME(sc->sc_dev), off, (u_long)sc->sc_in_len));
   1299       1.1       scw 		break;
   1300       1.1       scw 
   1301       1.1       scw 	case UTOPPY_RESP_FILE_END:
   1302       1.1       scw 		DPRINTF(UTOPPY_DBG_READ, ("%s: utoppy_readfile_next: "
   1303       1.1       scw 		    "UTOPPY_RESP_FILE_END: sending ACK\n",
   1304       1.1       scw 		    USBDEVNAME(sc->sc_dev)));
   1305       1.1       scw 		UTOPPY_OUT_INIT(sc);
   1306       1.1       scw 		utoppy_send_packet(sc, UTOPPY_CMD_ACK, UTOPPY_SHORT_TIMEOUT);
   1307       1.1       scw 		/*FALLTHROUGH*/
   1308       1.1       scw 
   1309       1.1       scw 	case UTOPPY_RESP_SUCCESS:
   1310       1.1       scw 		sc->sc_state = UTOPPY_STATE_IDLE;
   1311       1.1       scw 		(void) utoppy_turbo_mode(sc, 0);
   1312       1.1       scw 		DPRINTF(UTOPPY_DBG_READ, ("%s: utoppy_readfile_next: all "
   1313       1.1       scw 		    "done\n", USBDEVNAME(sc->sc_dev)));
   1314       1.1       scw 		break;
   1315       1.1       scw 
   1316       1.1       scw 	case UTOPPY_RESP_ERROR:
   1317       1.1       scw 	default:
   1318       1.1       scw 		DPRINTF(UTOPPY_DBG_READ, ("%s: utoppy_readfile_next: bad "
   1319       1.1       scw 		    "response code 0x%0x\n", USBDEVNAME(sc->sc_dev), resp));
   1320       1.1       scw 		utoppy_cancel(sc);
   1321       1.1       scw 		return (EIO);
   1322       1.1       scw 	}
   1323       1.1       scw 
   1324       1.1       scw 	return (0);
   1325       1.1       scw }
   1326       1.1       scw 
   1327       1.1       scw int
   1328       1.8  christos utoppyopen(dev_t dev, int flag, int mode,
   1329  1.8.10.3     itohy     usb_proc_ptr p)
   1330       1.1       scw {
   1331       1.1       scw 	struct utoppy_softc *sc;
   1332       1.1       scw 	int error = 0;
   1333       1.1       scw 
   1334       1.1       scw 	USB_GET_SC_OPEN(utoppy, UTOPPYUNIT(dev), sc);
   1335       1.1       scw 
   1336       1.1       scw 	if (sc == NULL || sc->sc_iface == NULL || sc->sc_dying)
   1337       1.1       scw 		return (ENXIO);
   1338       1.1       scw 
   1339       1.1       scw 	if (sc->sc_state != UTOPPY_STATE_CLOSED) {
   1340       1.1       scw 		DPRINTF(UTOPPY_DBG_OPEN, ("%s: utoppyopen: already open\n",
   1341       1.1       scw 		    USBDEVNAME(sc->sc_dev)));
   1342       1.1       scw 		return (EBUSY);
   1343       1.1       scw 	}
   1344       1.1       scw 
   1345       1.1       scw 	DPRINTF(UTOPPY_DBG_OPEN, ("%s: utoppyopen: opening...\n",
   1346       1.1       scw 	    USBDEVNAME(sc->sc_dev)));
   1347       1.1       scw 
   1348       1.1       scw 	sc->sc_refcnt++;
   1349       1.1       scw 	sc->sc_state = UTOPPY_STATE_OPENING;
   1350       1.1       scw 	sc->sc_turbo_mode = 0;
   1351       1.1       scw 	sc->sc_out_pipe = NULL;
   1352       1.1       scw 	sc->sc_in_pipe = NULL;
   1353       1.1       scw 
   1354       1.1       scw 	if (usbd_open_pipe(sc->sc_iface, sc->sc_out, 0, &sc->sc_out_pipe)) {
   1355       1.1       scw 		DPRINTF(UTOPPY_DBG_OPEN, ("%s: utoppyopen: usbd_open_pipe(OUT) "
   1356       1.1       scw 		    "failed\n", USBDEVNAME(sc->sc_dev)));
   1357       1.1       scw 		error = EIO;
   1358       1.1       scw 		goto done;
   1359       1.1       scw 	}
   1360       1.1       scw 
   1361       1.1       scw 	if (usbd_open_pipe(sc->sc_iface, sc->sc_in, 0, &sc->sc_in_pipe)) {
   1362       1.1       scw 		DPRINTF(UTOPPY_DBG_OPEN, ("%s: utoppyopen: usbd_open_pipe(IN) "
   1363       1.1       scw 		    "failed\n", USBDEVNAME(sc->sc_dev)));
   1364       1.1       scw 		error = EIO;
   1365       1.1       scw 		usbd_close_pipe(sc->sc_out_pipe);
   1366       1.1       scw 		sc->sc_out_pipe = NULL;
   1367       1.5       scw 		goto done;
   1368       1.1       scw 	}
   1369       1.1       scw 
   1370  1.8.10.2     itohy 	sc->sc_out_xfer = usbd_alloc_xfer(sc->sc_udev, sc->sc_out_pipe);
   1371  1.8.10.2     itohy 	if (sc->sc_out_xfer == NULL) {
   1372  1.8.10.2     itohy 		error = ENOMEM;
   1373  1.8.10.2     itohy 		goto error;
   1374  1.8.10.2     itohy 	}
   1375  1.8.10.2     itohy 
   1376  1.8.10.2     itohy 	sc->sc_out_buf = usbd_alloc_buffer(sc->sc_out_xfer, UTOPPY_FRAG_SIZE);
   1377  1.8.10.2     itohy 	if (sc->sc_out_buf == NULL) {
   1378  1.8.10.2     itohy 		error = ENOMEM;
   1379  1.8.10.2     itohy 		goto error;
   1380  1.8.10.2     itohy 	}
   1381  1.8.10.2     itohy 
   1382  1.8.10.2     itohy 	sc->sc_in_xfer = usbd_alloc_xfer(sc->sc_udev, sc->sc_in_pipe);
   1383  1.8.10.2     itohy 	if (sc->sc_in_xfer == NULL) {
   1384  1.8.10.2     itohy 		error = ENOMEM;
   1385  1.8.10.2     itohy 		goto error;
   1386  1.8.10.2     itohy 	}
   1387  1.8.10.2     itohy 
   1388  1.8.10.2     itohy 	sc->sc_in_buf = usbd_alloc_buffer(sc->sc_in_xfer, UTOPPY_FRAG_SIZE);
   1389  1.8.10.2     itohy 	if (sc->sc_in_buf == NULL) {
   1390  1.8.10.2     itohy 		error = ENOMEM;
   1391  1.8.10.2     itohy 		goto error;
   1392  1.8.10.2     itohy 	}
   1393  1.8.10.2     itohy 
   1394       1.1       scw 	sc->sc_out_data = malloc(UTOPPY_BSIZE + 1, M_DEVBUF, M_WAITOK);
   1395       1.1       scw 	if (sc->sc_out_data == NULL) {
   1396       1.1       scw 		error = ENOMEM;
   1397       1.1       scw 		goto error;
   1398       1.1       scw 	}
   1399       1.1       scw 
   1400       1.1       scw 	sc->sc_in_data = malloc(UTOPPY_BSIZE + 1, M_DEVBUF, M_WAITOK);
   1401       1.1       scw 	if (sc->sc_in_data == NULL) {
   1402       1.1       scw 		free(sc->sc_out_data, M_DEVBUF);
   1403       1.1       scw 		sc->sc_out_data = NULL;
   1404       1.1       scw 		error = ENOMEM;
   1405       1.1       scw 		goto error;
   1406       1.1       scw 	}
   1407       1.1       scw 
   1408       1.1       scw 	if ((error = utoppy_cancel(sc)) != 0)
   1409       1.1       scw 		goto error;
   1410       1.1       scw 
   1411       1.1       scw 	if ((error = utoppy_check_ready(sc)) != 0) {
   1412       1.1       scw 		DPRINTF(UTOPPY_DBG_OPEN, ("%s: utoppyopen: utoppy_check_ready()"
   1413       1.1       scw 		    " returned %d\n", USBDEVNAME(sc->sc_dev), error));
   1414       1.1       scw  error:
   1415       1.1       scw 		usbd_abort_pipe(sc->sc_out_pipe);
   1416  1.8.10.2     itohy 		if (sc->sc_out_xfer)
   1417  1.8.10.2     itohy 			usbd_free_xfer(sc->sc_out_xfer);
   1418       1.1       scw 		usbd_close_pipe(sc->sc_out_pipe);
   1419       1.1       scw 		sc->sc_out_pipe = NULL;
   1420  1.8.10.2     itohy 		sc->sc_out_xfer = NULL;
   1421       1.1       scw 		usbd_abort_pipe(sc->sc_in_pipe);
   1422  1.8.10.2     itohy 		if (sc->sc_in_xfer)
   1423  1.8.10.2     itohy 			usbd_free_xfer(sc->sc_in_xfer);
   1424       1.1       scw 		usbd_close_pipe(sc->sc_in_pipe);
   1425       1.1       scw 		sc->sc_in_pipe = NULL;
   1426  1.8.10.2     itohy 		sc->sc_in_xfer = NULL;
   1427       1.1       scw 	}
   1428       1.1       scw 
   1429       1.1       scw  done:
   1430       1.1       scw 	sc->sc_state = error ? UTOPPY_STATE_CLOSED : UTOPPY_STATE_IDLE;
   1431       1.1       scw 
   1432       1.1       scw 	DPRINTF(UTOPPY_DBG_OPEN, ("%s: utoppyopen: done. error %d, new state "
   1433       1.1       scw 	    "'%s'\n", USBDEVNAME(sc->sc_dev), error,
   1434       1.1       scw 	    utoppy_state_string(sc->sc_state)));
   1435       1.1       scw 
   1436       1.1       scw 	if (--sc->sc_refcnt < 0)
   1437       1.1       scw 		usb_detach_wakeup(USBDEV(sc->sc_dev));
   1438       1.1       scw 
   1439       1.1       scw 	return (error);
   1440       1.1       scw }
   1441       1.1       scw 
   1442       1.1       scw int
   1443       1.8  christos utoppyclose(dev_t dev, int flag, int mode,
   1444  1.8.10.3     itohy     usb_proc_ptr p)
   1445       1.1       scw {
   1446       1.1       scw 	struct utoppy_softc *sc;
   1447       1.1       scw 	usbd_status err;
   1448       1.1       scw 
   1449       1.1       scw 	USB_GET_SC(utoppy, UTOPPYUNIT(dev), sc);
   1450       1.1       scw 
   1451       1.1       scw 	DPRINTF(UTOPPY_DBG_CLOSE, ("%s: utoppyclose: closing...\n",
   1452       1.1       scw 	    USBDEVNAME(sc->sc_dev)));
   1453       1.1       scw 
   1454       1.1       scw 	if (sc->sc_state < UTOPPY_STATE_IDLE) {
   1455       1.1       scw 		/* We are being forced to close before the open completed. */
   1456       1.1       scw 		DPRINTF(UTOPPY_DBG_CLOSE, ("%s: utoppyclose: not properly open:"
   1457       1.1       scw 		    " %s\n", USBDEVNAME(sc->sc_dev),
   1458       1.1       scw 		    utoppy_state_string(sc->sc_state)));
   1459       1.1       scw 		return (0);
   1460       1.1       scw 	}
   1461       1.1       scw 
   1462       1.3  christos 	if (sc->sc_out_data)
   1463       1.3  christos 		(void) utoppy_cancel(sc);
   1464       1.1       scw 
   1465       1.1       scw 	if (sc->sc_out_pipe != NULL) {
   1466       1.1       scw 		if ((err = usbd_abort_pipe(sc->sc_out_pipe)) != 0)
   1467       1.1       scw 			printf("usbd_abort_pipe(OUT) returned %d\n", err);
   1468  1.8.10.2     itohy 		if (sc->sc_out_xfer)
   1469  1.8.10.2     itohy 			usbd_free_xfer(sc->sc_out_xfer);
   1470       1.1       scw 		if ((err = usbd_close_pipe(sc->sc_out_pipe)) != 0)
   1471       1.1       scw 			printf("usbd_close_pipe(OUT) returned %d\n", err);
   1472       1.1       scw 		sc->sc_out_pipe = NULL;
   1473  1.8.10.2     itohy 		sc->sc_out_xfer = NULL;
   1474       1.1       scw 	}
   1475       1.1       scw 
   1476       1.1       scw 	if (sc->sc_in_pipe != NULL) {
   1477       1.1       scw 		if ((err = usbd_abort_pipe(sc->sc_in_pipe)) != 0)
   1478       1.1       scw 			printf("usbd_abort_pipe(IN) returned %d\n", err);
   1479  1.8.10.2     itohy 		if (sc->sc_in_xfer)
   1480  1.8.10.2     itohy 			usbd_free_xfer(sc->sc_in_xfer);
   1481       1.1       scw 		if ((err = usbd_close_pipe(sc->sc_in_pipe)) != 0)
   1482       1.1       scw 			printf("usbd_close_pipe(IN) returned %d\n", err);
   1483       1.1       scw 		sc->sc_in_pipe = NULL;
   1484  1.8.10.2     itohy 		sc->sc_in_xfer = NULL;
   1485       1.1       scw 	}
   1486       1.1       scw 
   1487       1.1       scw 	if (sc->sc_out_data) {
   1488       1.1       scw 		free(sc->sc_out_data, M_DEVBUF);
   1489       1.1       scw 		sc->sc_out_data = NULL;
   1490       1.1       scw 	}
   1491       1.1       scw 
   1492       1.1       scw 	if (sc->sc_in_data) {
   1493       1.1       scw 		free(sc->sc_in_data, M_DEVBUF);
   1494       1.1       scw 		sc->sc_in_data = NULL;
   1495       1.1       scw 	}
   1496       1.1       scw 
   1497       1.1       scw 	sc->sc_state = UTOPPY_STATE_CLOSED;
   1498       1.1       scw 
   1499       1.1       scw 	DPRINTF(UTOPPY_DBG_CLOSE, ("%s: utoppyclose: done.\n",
   1500       1.1       scw 	    USBDEVNAME(sc->sc_dev)));
   1501       1.1       scw 
   1502       1.1       scw 	return (0);
   1503       1.1       scw }
   1504       1.1       scw 
   1505       1.1       scw int
   1506       1.8  christos utoppyread(dev_t dev, struct uio *uio, int flags)
   1507       1.1       scw {
   1508       1.1       scw 	struct utoppy_softc *sc;
   1509       1.1       scw 	struct utoppy_dirent ud;
   1510       1.1       scw 	size_t len;
   1511       1.1       scw 	int err;
   1512       1.1       scw 
   1513       1.1       scw 	USB_GET_SC(utoppy, UTOPPYUNIT(dev), sc);
   1514       1.1       scw 
   1515       1.1       scw 	if (sc->sc_dying)
   1516       1.1       scw 		return (EIO);
   1517       1.1       scw 
   1518       1.1       scw 	sc->sc_refcnt++;
   1519       1.1       scw 
   1520       1.1       scw 	DPRINTF(UTOPPY_DBG_READ, ("%s: utoppyread: reading: state '%s'\n",
   1521       1.1       scw 	    USBDEVNAME(sc->sc_dev), utoppy_state_string(sc->sc_state)));
   1522       1.1       scw 
   1523       1.1       scw 	switch (sc->sc_state) {
   1524       1.1       scw 	case UTOPPY_STATE_READDIR:
   1525       1.1       scw 		err = 0;
   1526       1.1       scw 		while (err == 0 && uio->uio_resid >= sizeof(ud) &&
   1527       1.1       scw 		    sc->sc_state != UTOPPY_STATE_IDLE) {
   1528       1.1       scw 			if (utoppy_readdir_decode(sc, &ud) == 0)
   1529       1.1       scw 				err = utoppy_readdir_next(sc);
   1530       1.1       scw 			else
   1531       1.1       scw 			if ((err = uiomove(&ud, sizeof(ud), uio)) != 0)
   1532       1.1       scw 				utoppy_cancel(sc);
   1533       1.1       scw 		}
   1534       1.1       scw 		break;
   1535       1.1       scw 
   1536       1.1       scw 	case UTOPPY_STATE_READFILE:
   1537       1.1       scw 		err = 0;
   1538       1.1       scw 		while (err == 0 && uio->uio_resid > 0 &&
   1539       1.1       scw 		    sc->sc_state != UTOPPY_STATE_IDLE) {
   1540       1.1       scw 			DPRINTF(UTOPPY_DBG_READ, ("%s: utoppyread: READFILE: "
   1541       1.1       scw 			    "resid %ld, bytes_left %ld\n",
   1542       1.1       scw 			    USBDEVNAME(sc->sc_dev), (u_long)uio->uio_resid,
   1543       1.1       scw 			    (u_long)sc->sc_in_len));
   1544       1.1       scw 
   1545       1.1       scw 			if (sc->sc_in_len == 0 &&
   1546       1.1       scw 			    (err = utoppy_readfile_next(sc)) != 0) {
   1547       1.1       scw 				DPRINTF(UTOPPY_DBG_READ, ("%s: utoppyread: "
   1548       1.1       scw 				    "READFILE: utoppy_readfile_next returned "
   1549       1.1       scw 				    "%d\n", USBDEVNAME(sc->sc_dev), err));
   1550       1.1       scw 				break;
   1551       1.1       scw 			}
   1552       1.1       scw 
   1553       1.1       scw 			len = min(uio->uio_resid, sc->sc_in_len);
   1554       1.1       scw 			if (len) {
   1555       1.1       scw 				err = uiomove(UTOPPY_IN_DATA(sc), len, uio);
   1556       1.1       scw 				if (err == 0) {
   1557       1.1       scw 					sc->sc_in_offset += len;
   1558       1.1       scw 					sc->sc_in_len -= len;
   1559       1.1       scw 				}
   1560       1.1       scw 			}
   1561       1.1       scw 		}
   1562       1.1       scw 		break;
   1563       1.1       scw 
   1564       1.1       scw 	case UTOPPY_STATE_IDLE:
   1565       1.1       scw 		err = 0;
   1566       1.1       scw 		break;
   1567       1.1       scw 
   1568       1.1       scw 	case UTOPPY_STATE_WRITEFILE:
   1569       1.1       scw 		err = EBUSY;
   1570       1.1       scw 		break;
   1571       1.1       scw 
   1572       1.1       scw 	default:
   1573       1.1       scw 		err = EIO;
   1574       1.1       scw 		break;
   1575       1.1       scw 	}
   1576       1.1       scw 
   1577       1.1       scw 	DPRINTF(UTOPPY_DBG_READ, ("%s: utoppyread: done. err %d, state '%s'\n",
   1578       1.1       scw 	    USBDEVNAME(sc->sc_dev), err, utoppy_state_string(sc->sc_state)));
   1579       1.1       scw 
   1580       1.1       scw 	if (--sc->sc_refcnt < 0)
   1581       1.1       scw 		usb_detach_wakeup(USBDEV(sc->sc_dev));
   1582       1.1       scw 
   1583       1.1       scw 	return (err);
   1584       1.1       scw }
   1585       1.1       scw 
   1586       1.1       scw int
   1587       1.8  christos utoppywrite(dev_t dev, struct uio *uio, int flags)
   1588       1.1       scw {
   1589       1.1       scw 	struct utoppy_softc *sc;
   1590       1.1       scw 	uint16_t resp;
   1591       1.1       scw 	size_t len;
   1592       1.1       scw 	int err;
   1593       1.1       scw 
   1594       1.1       scw 	USB_GET_SC(utoppy, UTOPPYUNIT(dev), sc);
   1595       1.1       scw 
   1596       1.1       scw 	if (sc->sc_dying)
   1597       1.1       scw 		return (EIO);
   1598       1.1       scw 
   1599       1.1       scw 	switch(sc->sc_state) {
   1600       1.1       scw 	case UTOPPY_STATE_WRITEFILE:
   1601       1.1       scw 		break;
   1602       1.1       scw 
   1603       1.1       scw 	case UTOPPY_STATE_IDLE:
   1604       1.1       scw 		return (0);
   1605       1.1       scw 
   1606       1.1       scw 	default:
   1607       1.1       scw 		return (EIO);
   1608       1.1       scw 	}
   1609       1.1       scw 
   1610       1.1       scw 	sc->sc_refcnt++;
   1611       1.1       scw 	err = 0;
   1612       1.1       scw 
   1613       1.1       scw 	DPRINTF(UTOPPY_DBG_WRITE, ("%s: utoppywrite: PRE-WRITEFILE: resid %ld, "
   1614       1.1       scw 	    "wr_size %lld, wr_offset %lld\n", USBDEVNAME(sc->sc_dev),
   1615       1.1       scw 	    (u_long)uio->uio_resid, sc->sc_wr_size, sc->sc_wr_offset));
   1616       1.1       scw 
   1617       1.1       scw 	while (sc->sc_state == UTOPPY_STATE_WRITEFILE &&
   1618       1.1       scw 	    (len = min(uio->uio_resid, sc->sc_wr_size)) != 0) {
   1619       1.1       scw 
   1620       1.1       scw 		len = min(len, UTOPPY_BSIZE - (UTOPPY_HEADER_SIZE +
   1621       1.1       scw 		    sizeof(uint64_t) + 3));
   1622       1.1       scw 
   1623       1.1       scw 		DPRINTF(UTOPPY_DBG_WRITE, ("%s: utoppywrite: uiomove(%ld)\n",
   1624       1.1       scw 		    USBDEVNAME(sc->sc_dev), (u_long)len));
   1625       1.1       scw 
   1626       1.1       scw 		UTOPPY_OUT_INIT(sc);
   1627       1.1       scw 		utoppy_add_64(sc, sc->sc_wr_offset);
   1628       1.1       scw 
   1629       1.1       scw 		err = uiomove(utoppy_current_ptr(sc->sc_out_data), len, uio);
   1630       1.1       scw 		if (err) {
   1631       1.1       scw 			DPRINTF(UTOPPY_DBG_WRITE, ("%s: utoppywrite: uiomove() "
   1632       1.1       scw 			    "returned %d\n", USBDEVNAME(sc->sc_dev), err));
   1633       1.1       scw 			break;
   1634       1.1       scw 		}
   1635       1.1       scw 
   1636       1.1       scw 		utoppy_advance_ptr(sc->sc_out_data, len);
   1637       1.1       scw 
   1638       1.1       scw 		err = utoppy_command(sc, UTOPPY_RESP_FILE_DATA,
   1639       1.1       scw 		    UTOPPY_LONG_TIMEOUT, &resp);
   1640       1.1       scw 		if (err) {
   1641       1.1       scw 			DPRINTF(UTOPPY_DBG_WRITE, ("%s: utoppywrite: "
   1642       1.1       scw 			    "utoppy_command(UTOPPY_RESP_FILE_DATA) "
   1643       1.1       scw 			    "returned %d\n", USBDEVNAME(sc->sc_dev), err));
   1644       1.1       scw 			break;
   1645       1.1       scw 		}
   1646       1.1       scw 		if (resp != UTOPPY_RESP_SUCCESS) {
   1647       1.1       scw 			DPRINTF(UTOPPY_DBG_WRITE, ("%s: utoppywrite: "
   1648       1.1       scw 			    "utoppy_command(UTOPPY_RESP_FILE_DATA) returned "
   1649       1.1       scw 			    "bad response 0x%x\n", USBDEVNAME(sc->sc_dev),
   1650       1.1       scw 			    resp));
   1651       1.1       scw 			utoppy_cancel(sc);
   1652       1.1       scw 			err = EIO;
   1653       1.1       scw 			break;
   1654       1.1       scw 		}
   1655       1.1       scw 
   1656       1.1       scw 		sc->sc_wr_offset += len;
   1657       1.1       scw 		sc->sc_wr_size -= len;
   1658       1.1       scw 	}
   1659       1.1       scw 
   1660       1.1       scw 	DPRINTF(UTOPPY_DBG_WRITE, ("%s: utoppywrite: POST-WRITEFILE: resid %ld,"
   1661       1.1       scw 	    " wr_size %lld, wr_offset %lld, err %d\n", USBDEVNAME(sc->sc_dev),
   1662       1.1       scw 	    (u_long)uio->uio_resid, sc->sc_wr_size, sc->sc_wr_offset, err));
   1663       1.1       scw 
   1664       1.1       scw 	if (err == 0 && sc->sc_wr_size == 0) {
   1665       1.1       scw 		DPRINTF(UTOPPY_DBG_WRITE, ("%s: utoppywrite: sending "
   1666       1.1       scw 		    "FILE_END...\n", USBDEVNAME(sc->sc_dev)));
   1667       1.1       scw 		UTOPPY_OUT_INIT(sc);
   1668       1.1       scw 		err = utoppy_command(sc, UTOPPY_RESP_FILE_END,
   1669       1.1       scw 		    UTOPPY_LONG_TIMEOUT, &resp);
   1670       1.1       scw 		if (err) {
   1671       1.1       scw 			DPRINTF(UTOPPY_DBG_WRITE, ("%s: utoppywrite: "
   1672       1.1       scw 			    "utoppy_command(UTOPPY_RESP_FILE_END) returned "
   1673       1.1       scw 			    "%d\n", USBDEVNAME(sc->sc_dev), err));
   1674       1.1       scw 
   1675       1.1       scw 			utoppy_cancel(sc);
   1676       1.1       scw 		}
   1677       1.1       scw 
   1678       1.1       scw 		sc->sc_state = UTOPPY_STATE_IDLE;
   1679       1.1       scw 		DPRINTF(UTOPPY_DBG_WRITE, ("%s: utoppywrite: state %s\n",
   1680       1.1       scw 		    USBDEVNAME(sc->sc_dev), utoppy_state_string(sc->sc_state)));
   1681       1.1       scw 	}
   1682       1.1       scw 
   1683       1.1       scw 	if (--sc->sc_refcnt < 0)
   1684       1.1       scw 		usb_detach_wakeup(USBDEV(sc->sc_dev));
   1685       1.1       scw 
   1686       1.1       scw 	return (err);
   1687       1.1       scw }
   1688       1.1       scw 
   1689       1.1       scw int
   1690  1.8.10.3     itohy utoppyioctl(dev_t dev, u_long cmd, usb_ioctlarg_t data, int flag,
   1691  1.8.10.3     itohy     usb_proc_ptr p)
   1692       1.1       scw {
   1693       1.1       scw 	struct utoppy_softc *sc;
   1694       1.1       scw 	struct utoppy_rename *ur;
   1695       1.1       scw 	struct utoppy_readfile *urf;
   1696       1.1       scw 	struct utoppy_writefile *uw;
   1697       1.1       scw 	char uwf[UTOPPY_MAX_FILENAME_LEN + 1], *uwfp;
   1698       1.1       scw 	uint16_t resp;
   1699       1.1       scw 	int err;
   1700       1.1       scw 
   1701       1.1       scw 	USB_GET_SC(utoppy, UTOPPYUNIT(dev), sc);
   1702       1.1       scw 
   1703       1.1       scw 	if (sc->sc_dying)
   1704       1.1       scw 		return (EIO);
   1705       1.1       scw 
   1706       1.1       scw 	DPRINTF(UTOPPY_DBG_IOCTL, ("%s: utoppyioctl: cmd 0x%08lx, state '%s'\n",
   1707       1.1       scw 	    USBDEVNAME(sc->sc_dev), cmd, utoppy_state_string(sc->sc_state)));
   1708       1.1       scw 
   1709       1.1       scw 	if (sc->sc_state != UTOPPY_STATE_IDLE && cmd != UTOPPYIOCANCEL) {
   1710       1.1       scw 		DPRINTF(UTOPPY_DBG_IOCTL, ("%s: utoppyioctl: still busy.\n",
   1711       1.1       scw 		    USBDEVNAME(sc->sc_dev)));
   1712       1.1       scw 		return (EBUSY);
   1713       1.1       scw 	}
   1714       1.1       scw 
   1715       1.1       scw 	sc->sc_refcnt++;
   1716       1.1       scw 
   1717       1.1       scw 	switch (cmd) {
   1718       1.1       scw 	case UTOPPYIOTURBO:
   1719       1.1       scw 		err = 0;
   1720       1.1       scw 		sc->sc_turbo_mode = *((int *)data) ? 1 : 0;
   1721       1.1       scw 		DPRINTF(UTOPPY_DBG_IOCTL, ("%s: utoppyioctl: UTOPPYIOTURBO: "
   1722       1.1       scw 		    "%s\n", USBDEVNAME(sc->sc_dev), sc->sc_turbo_mode ? "On" :
   1723       1.1       scw 		    "Off"));
   1724       1.1       scw 		break;
   1725       1.1       scw 
   1726       1.1       scw 	case UTOPPYIOCANCEL:
   1727       1.1       scw 		DPRINTF(UTOPPY_DBG_IOCTL, ("%s: utoppyioctl: UTOPPYIOCANCEL\n",
   1728       1.1       scw 		    USBDEVNAME(sc->sc_dev)));
   1729       1.1       scw 		err = utoppy_cancel(sc);
   1730       1.1       scw 		break;
   1731       1.1       scw 
   1732       1.1       scw 	case UTOPPYIOREBOOT:
   1733       1.1       scw 		DPRINTF(UTOPPY_DBG_IOCTL, ("%s: utoppyioctl: UTOPPYIOREBOOT\n",
   1734       1.1       scw 		    USBDEVNAME(sc->sc_dev)));
   1735       1.1       scw 		UTOPPY_OUT_INIT(sc);
   1736       1.1       scw 		err = utoppy_command(sc, UTOPPY_CMD_RESET, UTOPPY_LONG_TIMEOUT,
   1737       1.1       scw 		    &resp);
   1738       1.1       scw 		if (err)
   1739       1.1       scw 			break;
   1740       1.1       scw 
   1741       1.1       scw 		if (resp != UTOPPY_RESP_SUCCESS)
   1742       1.1       scw 			err = EIO;
   1743       1.1       scw 		break;
   1744       1.1       scw 
   1745       1.1       scw 	case UTOPPYIOSTATS:
   1746       1.1       scw 		DPRINTF(UTOPPY_DBG_IOCTL, ("%s: utoppyioctl: UTOPPYIOSTATS\n",
   1747       1.1       scw 		    USBDEVNAME(sc->sc_dev)));
   1748       1.1       scw 		err = utoppy_stats(sc, (struct utoppy_stats *)data);
   1749       1.1       scw 		break;
   1750       1.1       scw 
   1751       1.1       scw 	case UTOPPYIORENAME:
   1752       1.1       scw 		DPRINTF(UTOPPY_DBG_IOCTL, ("%s: utoppyioctl: UTOPPYIORENAME\n",
   1753       1.1       scw 		    USBDEVNAME(sc->sc_dev)));
   1754       1.1       scw 		ur = (struct utoppy_rename *)data;
   1755       1.1       scw 		UTOPPY_OUT_INIT(sc);
   1756       1.1       scw 
   1757       1.1       scw 		if ((err = utoppy_add_path(sc, ur->ur_old_path, 1)) != 0)
   1758       1.1       scw 			break;
   1759       1.1       scw 		if ((err = utoppy_add_path(sc, ur->ur_new_path, 1)) != 0)
   1760       1.1       scw 			break;
   1761       1.1       scw 
   1762       1.1       scw 		err = utoppy_command(sc, UTOPPY_CMD_RENAME, UTOPPY_LONG_TIMEOUT,
   1763       1.1       scw 		    &resp);
   1764       1.1       scw 		if (err)
   1765       1.1       scw 			break;
   1766       1.1       scw 
   1767       1.1       scw 		if (resp != UTOPPY_RESP_SUCCESS)
   1768       1.1       scw 			err = EIO;
   1769       1.1       scw 		break;
   1770       1.1       scw 
   1771       1.1       scw 	case UTOPPYIOMKDIR:
   1772       1.1       scw 		DPRINTF(UTOPPY_DBG_IOCTL, ("%s: utoppyioctl: UTOPPYIOMKDIR\n",
   1773       1.1       scw 		    USBDEVNAME(sc->sc_dev)));
   1774       1.1       scw 		UTOPPY_OUT_INIT(sc);
   1775       1.1       scw 		err = utoppy_add_path(sc, *((const char **)data), 1);
   1776       1.1       scw 		if (err)
   1777       1.1       scw 			break;
   1778       1.1       scw 
   1779       1.1       scw 		err = utoppy_command(sc, UTOPPY_CMD_MKDIR, UTOPPY_LONG_TIMEOUT,
   1780       1.1       scw 		    &resp);
   1781       1.1       scw 		if (err)
   1782       1.1       scw 			break;
   1783       1.1       scw 
   1784       1.1       scw 		if (resp != UTOPPY_RESP_SUCCESS)
   1785       1.1       scw 			err = EIO;
   1786       1.1       scw 		break;
   1787       1.1       scw 
   1788       1.1       scw 	case UTOPPYIODELETE:
   1789       1.1       scw 		DPRINTF(UTOPPY_DBG_IOCTL, ("%s: utoppyioctl: UTOPPYIODELETE\n",
   1790       1.1       scw 		    USBDEVNAME(sc->sc_dev)));
   1791       1.1       scw 		UTOPPY_OUT_INIT(sc);
   1792       1.1       scw 		err = utoppy_add_path(sc, *((const char **)data), 0);
   1793       1.1       scw 		if (err)
   1794       1.1       scw 			break;
   1795       1.1       scw 
   1796       1.1       scw 		err = utoppy_command(sc, UTOPPY_CMD_DELETE, UTOPPY_LONG_TIMEOUT,
   1797       1.1       scw 		    &resp);
   1798       1.1       scw 		if (err)
   1799       1.1       scw 			break;
   1800       1.1       scw 
   1801       1.1       scw 		if (resp != UTOPPY_RESP_SUCCESS)
   1802       1.1       scw 			err = EIO;
   1803       1.1       scw 		break;
   1804       1.1       scw 
   1805       1.1       scw 	case UTOPPYIOREADDIR:
   1806       1.1       scw 		DPRINTF(UTOPPY_DBG_IOCTL, ("%s: utoppyioctl: UTOPPYIOREADDIR\n",
   1807       1.1       scw 		    USBDEVNAME(sc->sc_dev)));
   1808       1.1       scw 		UTOPPY_OUT_INIT(sc);
   1809       1.1       scw 		err = utoppy_add_path(sc, *((const char **)data), 0);
   1810       1.1       scw 		if (err) {
   1811       1.1       scw 			DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppyioctl: "
   1812       1.1       scw 			    "utoppy_add_path() returned %d\n",
   1813       1.1       scw 			    USBDEVNAME(sc->sc_dev), err));
   1814       1.1       scw 			break;
   1815       1.1       scw 		}
   1816       1.1       scw 
   1817       1.1       scw 		err = utoppy_send_packet(sc, UTOPPY_CMD_READDIR,
   1818       1.1       scw 		    UTOPPY_LONG_TIMEOUT);
   1819       1.1       scw 		if (err != 0) {
   1820       1.1       scw 			DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppyioctl: "
   1821       1.1       scw 			    "UTOPPY_CMD_READDIR returned %d\n",
   1822       1.1       scw 			    USBDEVNAME(sc->sc_dev), err));
   1823       1.1       scw 			break;
   1824       1.1       scw 		}
   1825       1.1       scw 
   1826       1.1       scw 		err = utoppy_readdir_next(sc);
   1827       1.1       scw 		if (err) {
   1828       1.1       scw 			DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppyioctl: "
   1829       1.1       scw 			    "utoppy_readdir_next() returned %d\n",
   1830       1.1       scw 			    USBDEVNAME(sc->sc_dev), err));
   1831       1.1       scw 		}
   1832       1.1       scw 		break;
   1833       1.1       scw 
   1834       1.1       scw 	case UTOPPYIOREADFILE:
   1835       1.1       scw 		urf = (struct utoppy_readfile *)data;
   1836       1.1       scw 
   1837       1.1       scw 		DPRINTF(UTOPPY_DBG_IOCTL,("%s: utoppyioctl: UTOPPYIOREADFILE "
   1838       1.1       scw 		    "%s, offset %lld\n", USBDEVNAME(sc->sc_dev), urf->ur_path,
   1839       1.1       scw 		    urf->ur_offset));
   1840       1.1       scw 
   1841       1.1       scw 		if ((err = utoppy_turbo_mode(sc, sc->sc_turbo_mode)) != 0)
   1842       1.1       scw 			break;
   1843       1.1       scw 
   1844       1.1       scw 		UTOPPY_OUT_INIT(sc);
   1845       1.1       scw 		utoppy_add_8(sc, UTOPPY_FILE_READ);
   1846       1.1       scw 
   1847       1.1       scw 		if ((err = utoppy_add_path(sc, urf->ur_path, 1)) != 0)
   1848       1.1       scw 			break;
   1849       1.1       scw 
   1850       1.1       scw 		utoppy_add_64(sc, urf->ur_offset);
   1851       1.1       scw 
   1852       1.1       scw 		sc->sc_state = UTOPPY_STATE_READFILE;
   1853       1.1       scw 		sc->sc_in_offset = 0;
   1854       1.1       scw 
   1855       1.1       scw 		err = utoppy_send_packet(sc, UTOPPY_CMD_FILE,
   1856       1.1       scw 		    UTOPPY_LONG_TIMEOUT);
   1857       1.1       scw 		if (err == 0)
   1858       1.1       scw 			err = utoppy_readfile_next(sc);
   1859       1.1       scw 		break;
   1860       1.1       scw 
   1861       1.1       scw 	case UTOPPYIOWRITEFILE:
   1862       1.1       scw 		uw = (struct utoppy_writefile *)data;
   1863       1.1       scw 
   1864       1.1       scw 		DPRINTF(UTOPPY_DBG_IOCTL,("%s: utoppyioctl: UTOPPYIOWRITEFILE "
   1865       1.1       scw 		    "%s, size %lld, offset %lld\n", USBDEVNAME(sc->sc_dev),
   1866       1.1       scw 		    uw->uw_path, uw->uw_size, uw->uw_offset));
   1867       1.1       scw 
   1868       1.1       scw 		if ((err = utoppy_turbo_mode(sc, sc->sc_turbo_mode)) != 0)
   1869       1.1       scw 			break;
   1870       1.1       scw 
   1871       1.1       scw 		UTOPPY_OUT_INIT(sc);
   1872       1.1       scw 		utoppy_add_8(sc, UTOPPY_FILE_WRITE);
   1873       1.1       scw 		uwfp = utoppy_current_ptr(sc->sc_out_data);
   1874       1.1       scw 
   1875       1.1       scw 		if ((err = utoppy_add_path(sc, uw->uw_path, 1)) != 0) {
   1876       1.1       scw 			DPRINTF(UTOPPY_DBG_WRITE,("%s: utoppyioctl: add_path() "
   1877       1.1       scw 			    "returned %d\n", USBDEVNAME(sc->sc_dev), err));
   1878       1.1       scw 			break;
   1879       1.1       scw 		}
   1880       1.1       scw 
   1881       1.1       scw 		strncpy(uwf, &uwfp[2], sizeof(uwf));
   1882       1.1       scw 		utoppy_add_64(sc, uw->uw_offset);
   1883       1.1       scw 
   1884       1.1       scw 		err = utoppy_command(sc, UTOPPY_CMD_FILE, UTOPPY_LONG_TIMEOUT,
   1885       1.1       scw 		    &resp);
   1886       1.1       scw 		if (err) {
   1887       1.1       scw 			DPRINTF(UTOPPY_DBG_WRITE,("%s: utoppyioctl: "
   1888       1.1       scw 			    "utoppy_command(UTOPPY_CMD_FILE) returned "
   1889       1.1       scw 			    "%d\n", USBDEVNAME(sc->sc_dev), err));
   1890       1.1       scw 			break;
   1891       1.1       scw 		}
   1892       1.1       scw 		if (resp != UTOPPY_RESP_SUCCESS) {
   1893       1.1       scw 			DPRINTF(UTOPPY_DBG_WRITE,("%s: utoppyioctl: "
   1894       1.1       scw 			    "utoppy_command(UTOPPY_CMD_FILE) returned "
   1895       1.1       scw 			    "bad response 0x%x\n", USBDEVNAME(sc->sc_dev),
   1896       1.1       scw 			    resp));
   1897       1.1       scw 			err = EIO;
   1898       1.1       scw 			break;
   1899       1.1       scw 		}
   1900       1.1       scw 
   1901       1.1       scw 		UTOPPY_OUT_INIT(sc);
   1902       1.1       scw 		utoppy_timestamp_encode(sc, uw->uw_mtime);
   1903       1.1       scw 		utoppy_add_8(sc, UTOPPY_FTYPE_FILE);
   1904       1.1       scw 		utoppy_add_64(sc, uw->uw_size);
   1905       1.1       scw 		utoppy_add_string(sc, uwf, sizeof(uwf));
   1906       1.1       scw 		utoppy_add_32(sc, 0);
   1907       1.1       scw 
   1908       1.1       scw 		err = utoppy_command(sc, UTOPPY_RESP_FILE_HEADER,
   1909       1.1       scw 		    UTOPPY_LONG_TIMEOUT, &resp);
   1910       1.1       scw 		if (err) {
   1911       1.1       scw 			DPRINTF(UTOPPY_DBG_WRITE,("%s: utoppyioctl: "
   1912       1.1       scw 			    "utoppy_command(UTOPPY_RESP_FILE_HEADER) "
   1913       1.1       scw 			    "returned %d\n", USBDEVNAME(sc->sc_dev), err));
   1914       1.1       scw 			break;
   1915       1.1       scw 		}
   1916       1.1       scw 		if (resp != UTOPPY_RESP_SUCCESS) {
   1917       1.1       scw 			DPRINTF(UTOPPY_DBG_WRITE,("%s: utoppyioctl: "
   1918       1.1       scw 			    "utoppy_command(UTOPPY_RESP_FILE_HEADER) "
   1919       1.1       scw 			    "returned bad response 0x%x\n",
   1920       1.1       scw 			    USBDEVNAME(sc->sc_dev), resp));
   1921       1.1       scw 			err = EIO;
   1922       1.1       scw 			break;
   1923       1.1       scw 		}
   1924       1.1       scw 
   1925       1.1       scw 		sc->sc_wr_offset = uw->uw_offset;
   1926       1.1       scw 		sc->sc_wr_size = uw->uw_size;
   1927       1.1       scw 		sc->sc_state = UTOPPY_STATE_WRITEFILE;
   1928       1.1       scw 
   1929       1.1       scw 		DPRINTF(UTOPPY_DBG_WRITE,("%s: utoppyioctl: Changing state to "
   1930       1.1       scw 		    "%s. wr_offset %lld, wr_size %lld\n",
   1931       1.1       scw 		    USBDEVNAME(sc->sc_dev), utoppy_state_string(sc->sc_state),
   1932       1.1       scw 		    sc->sc_wr_offset, sc->sc_wr_size));
   1933       1.1       scw 		break;
   1934       1.1       scw 
   1935       1.1       scw 	default:
   1936       1.1       scw 		DPRINTF(UTOPPY_DBG_IOCTL,("%s: utoppyioctl: Invalid cmd\n",
   1937       1.1       scw 		    USBDEVNAME(sc->sc_dev)));
   1938       1.1       scw 		err = ENODEV;
   1939       1.1       scw 		break;
   1940       1.1       scw 	}
   1941       1.1       scw 
   1942       1.1       scw 	DPRINTF(UTOPPY_DBG_IOCTL,("%s: utoppyioctl: done. err %d, state '%s'\n",
   1943       1.1       scw 	    USBDEVNAME(sc->sc_dev), err, utoppy_state_string(sc->sc_state)));
   1944       1.1       scw 
   1945       1.1       scw 	if (err)
   1946       1.1       scw 		utoppy_cancel(sc);
   1947       1.1       scw 
   1948       1.1       scw 	if (--sc->sc_refcnt < 0)
   1949       1.1       scw 		usb_detach_wakeup(USBDEV(sc->sc_dev));
   1950       1.1       scw 
   1951       1.1       scw 	return (err);
   1952       1.1       scw }
   1953