version 1.22, 2009/08/16 14:18:49 |
version 1.23, 2009/09/04 17:53:58 |
Line 127 Static const struct cdce_type cdce_devs[ |
|
Line 127 Static const struct cdce_type cdce_devs[ |
|
}; |
}; |
#define cdce_lookup(v, p) ((const struct cdce_type *)usb_lookup(cdce_devs, v, p)) |
#define cdce_lookup(v, p) ((const struct cdce_type *)usb_lookup(cdce_devs, v, p)) |
|
|
USB_DECLARE_DRIVER(cdce); |
int cdce_match(device_t, cfdata_t, void *); |
|
void cdce_attach(device_t, device_t, void *); |
|
int cdce_detach(device_t, int); |
|
int cdce_activate(device_t, enum devact); |
|
extern struct cfdriver cdce_cd; |
|
CFATTACH_DECL_NEW(cdce, sizeof(struct cdce_softc), cdce_match, cdce_attach, |
|
cdce_detach, cdce_activate); |
|
|
USB_MATCH(cdce) |
int |
|
cdce_match(device_t parent, cfdata_t match, void *aux) |
{ |
{ |
USB_IFMATCH_START(cdce, uaa); |
struct usbif_attach_arg *uaa = aux; |
|
|
if (cdce_lookup(uaa->vendor, uaa->product) != NULL) |
if (cdce_lookup(uaa->vendor, uaa->product) != NULL) |
return (UMATCH_VENDOR_PRODUCT); |
return (UMATCH_VENDOR_PRODUCT); |
|
|
return (UMATCH_NONE); |
return (UMATCH_NONE); |
} |
} |
|
|
USB_ATTACH(cdce) |
void |
|
cdce_attach(device_t parent, device_t self, void *aux) |
{ |
{ |
USB_IFATTACH_START(cdce, sc, uaa); |
struct cdce_softc *sc = device_private(self); |
|
struct usbif_attach_arg *uaa = aux; |
char *devinfop; |
char *devinfop; |
int s; |
int s; |
struct ifnet *ifp; |
struct ifnet *ifp; |
Line 162 USB_ATTACH(cdce) |
|
Line 171 USB_ATTACH(cdce) |
|
char eaddr_str[USB_MAX_ENCODED_STRING_LEN]; |
char eaddr_str[USB_MAX_ENCODED_STRING_LEN]; |
|
|
devinfop = usbd_devinfo_alloc(dev, 0); |
devinfop = usbd_devinfo_alloc(dev, 0); |
USB_ATTACH_SETUP; |
aprint_naive("\n"); |
|
aprint_normal("\n"); |
sc->cdce_dev = self; |
sc->cdce_dev = self; |
aprint_normal_dev(self, "%s\n", devinfop); |
aprint_normal_dev(self, "%s\n", devinfop); |
usbd_devinfo_free(devinfop); |
usbd_devinfo_free(devinfop); |
Line 181 USB_ATTACH(cdce) |
|
Line 191 USB_ATTACH(cdce) |
|
UDESC_CS_INTERFACE, UDESCSUB_CDC_UNION); |
UDESC_CS_INTERFACE, UDESCSUB_CDC_UNION); |
if (ud == NULL) { |
if (ud == NULL) { |
aprint_error_dev(self, "no union descriptor\n"); |
aprint_error_dev(self, "no union descriptor\n"); |
USB_ATTACH_ERROR_RETURN; |
return; |
} |
} |
data_ifcno = ud->bSlaveInterface[0]; |
data_ifcno = ud->bSlaveInterface[0]; |
|
|
Line 200 USB_ATTACH(cdce) |
|
Line 210 USB_ATTACH(cdce) |
|
|
|
if (sc->cdce_data_iface == NULL) { |
if (sc->cdce_data_iface == NULL) { |
aprint_error_dev(self, "no data interface\n"); |
aprint_error_dev(self, "no data interface\n"); |
USB_ATTACH_ERROR_RETURN; |
return; |
} |
} |
|
|
/* |
/* |
Line 229 USB_ATTACH(cdce) |
|
Line 239 USB_ATTACH(cdce) |
|
if (usbd_set_interface(sc->cdce_data_iface, j)) { |
if (usbd_set_interface(sc->cdce_data_iface, j)) { |
aprint_error_dev(sc->cdce_dev, |
aprint_error_dev(sc->cdce_dev, |
"setting alternate interface failed\n"); |
"setting alternate interface failed\n"); |
USB_ATTACH_ERROR_RETURN; |
return; |
} |
} |
/* Find endpoints. */ |
/* Find endpoints. */ |
id = usbd_get_interface_descriptor(sc->cdce_data_iface); |
id = usbd_get_interface_descriptor(sc->cdce_data_iface); |
Line 239 USB_ATTACH(cdce) |
|
Line 249 USB_ATTACH(cdce) |
|
if (!ed) { |
if (!ed) { |
aprint_error_dev(self, |
aprint_error_dev(self, |
"could not read endpoint descriptor\n"); |
"could not read endpoint descriptor\n"); |
USB_ATTACH_ERROR_RETURN; |
return; |
} |
} |
if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && |
if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && |
UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { |
UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { |
Line 262 USB_ATTACH(cdce) |
|
Line 272 USB_ATTACH(cdce) |
|
|
|
if (sc->cdce_bulkin_no == -1) { |
if (sc->cdce_bulkin_no == -1) { |
aprint_error_dev(self, "could not find data bulk in\n"); |
aprint_error_dev(self, "could not find data bulk in\n"); |
USB_ATTACH_ERROR_RETURN; |
return; |
} |
} |
if (sc->cdce_bulkout_no == -1 ) { |
if (sc->cdce_bulkout_no == -1 ) { |
aprint_error_dev(self, "could not find data bulk out\n"); |
aprint_error_dev(self, "could not find data bulk out\n"); |
USB_ATTACH_ERROR_RETURN; |
return; |
} |
} |
|
|
ue = (const usb_cdc_ethernet_descriptor_t *)usb_find_desc(dev, |
ue = (const usb_cdc_ethernet_descriptor_t *)usb_find_desc(dev, |
Line 290 USB_ATTACH(cdce) |
|
Line 300 USB_ATTACH(cdce) |
|
ifp->if_ioctl = cdce_ioctl; |
ifp->if_ioctl = cdce_ioctl; |
ifp->if_start = cdce_start; |
ifp->if_start = cdce_start; |
ifp->if_watchdog = cdce_watchdog; |
ifp->if_watchdog = cdce_watchdog; |
strncpy(ifp->if_xname, USBDEVNAME(sc->cdce_dev), IFNAMSIZ); |
strncpy(ifp->if_xname, device_xname(sc->cdce_dev), IFNAMSIZ); |
|
|
IFQ_SET_READY(&ifp->if_snd); |
IFQ_SET_READY(&ifp->if_snd); |
|
|
if_attach(ifp); |
if_attach(ifp); |
Ether_ifattach(ifp, eaddr); |
ether_ifattach(ifp, eaddr); |
|
|
sc->cdce_attached = 1; |
sc->cdce_attached = 1; |
splx(s); |
splx(s); |
|
|
usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->cdce_udev, |
usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->cdce_udev, |
USBDEV(sc->cdce_dev)); |
(sc->cdce_dev)); |
|
|
USB_ATTACH_SUCCESS_RETURN; |
return; |
} |
} |
|
|
USB_DETACH(cdce) |
int |
|
cdce_detach(device_t self, int flags) |
{ |
{ |
USB_DETACH_START(cdce, sc); |
struct cdce_softc *sc = device_private(self); |
struct ifnet *ifp = GET_IFP(sc); |
struct ifnet *ifp = GET_IFP(sc); |
int s; |
int s; |
|
|
Line 408 cdce_stop(struct cdce_softc *sc) |
|
Line 419 cdce_stop(struct cdce_softc *sc) |
|
err = usbd_abort_pipe(sc->cdce_bulkin_pipe); |
err = usbd_abort_pipe(sc->cdce_bulkin_pipe); |
if (err) |
if (err) |
printf("%s: abort rx pipe failed: %s\n", |
printf("%s: abort rx pipe failed: %s\n", |
USBDEVNAME(sc->cdce_dev), usbd_errstr(err)); |
device_xname(sc->cdce_dev), usbd_errstr(err)); |
err = usbd_close_pipe(sc->cdce_bulkin_pipe); |
err = usbd_close_pipe(sc->cdce_bulkin_pipe); |
if (err) |
if (err) |
printf("%s: close rx pipe failed: %s\n", |
printf("%s: close rx pipe failed: %s\n", |
USBDEVNAME(sc->cdce_dev), usbd_errstr(err)); |
device_xname(sc->cdce_dev), usbd_errstr(err)); |
sc->cdce_bulkin_pipe = NULL; |
sc->cdce_bulkin_pipe = NULL; |
} |
} |
|
|
Line 420 cdce_stop(struct cdce_softc *sc) |
|
Line 431 cdce_stop(struct cdce_softc *sc) |
|
err = usbd_abort_pipe(sc->cdce_bulkout_pipe); |
err = usbd_abort_pipe(sc->cdce_bulkout_pipe); |
if (err) |
if (err) |
printf("%s: abort tx pipe failed: %s\n", |
printf("%s: abort tx pipe failed: %s\n", |
USBDEVNAME(sc->cdce_dev), usbd_errstr(err)); |
device_xname(sc->cdce_dev), usbd_errstr(err)); |
err = usbd_close_pipe(sc->cdce_bulkout_pipe); |
err = usbd_close_pipe(sc->cdce_bulkout_pipe); |
if (err) |
if (err) |
printf("%s: close tx pipe failed: %s\n", |
printf("%s: close tx pipe failed: %s\n", |
USBDEVNAME(sc->cdce_dev), usbd_errstr(err)); |
device_xname(sc->cdce_dev), usbd_errstr(err)); |
sc->cdce_bulkout_pipe = NULL; |
sc->cdce_bulkout_pipe = NULL; |
} |
} |
|
|
Line 525 cdce_watchdog(struct ifnet *ifp) |
|
Line 536 cdce_watchdog(struct ifnet *ifp) |
|
return; |
return; |
|
|
ifp->if_oerrors++; |
ifp->if_oerrors++; |
printf("%s: watchdog timeout\n", USBDEVNAME(sc->cdce_dev)); |
printf("%s: watchdog timeout\n", device_xname(sc->cdce_dev)); |
} |
} |
|
|
Static void |
Static void |
Line 543 cdce_init(void *xsc) |
|
Line 554 cdce_init(void *xsc) |
|
s = splnet(); |
s = splnet(); |
|
|
if (cdce_tx_list_init(sc) == ENOBUFS) { |
if (cdce_tx_list_init(sc) == ENOBUFS) { |
printf("%s: tx list init failed\n", USBDEVNAME(sc->cdce_dev)); |
printf("%s: tx list init failed\n", device_xname(sc->cdce_dev)); |
splx(s); |
splx(s); |
return; |
return; |
} |
} |
|
|
if (cdce_rx_list_init(sc) == ENOBUFS) { |
if (cdce_rx_list_init(sc) == ENOBUFS) { |
printf("%s: rx list init failed\n", USBDEVNAME(sc->cdce_dev)); |
printf("%s: rx list init failed\n", device_xname(sc->cdce_dev)); |
splx(s); |
splx(s); |
return; |
return; |
} |
} |
Line 559 cdce_init(void *xsc) |
|
Line 570 cdce_init(void *xsc) |
|
err = usbd_open_pipe(sc->cdce_data_iface, sc->cdce_bulkin_no, |
err = usbd_open_pipe(sc->cdce_data_iface, sc->cdce_bulkin_no, |
USBD_EXCLUSIVE_USE, &sc->cdce_bulkin_pipe); |
USBD_EXCLUSIVE_USE, &sc->cdce_bulkin_pipe); |
if (err) { |
if (err) { |
printf("%s: open rx pipe failed: %s\n", USBDEVNAME(sc->cdce_dev), |
printf("%s: open rx pipe failed: %s\n", device_xname(sc->cdce_dev), |
usbd_errstr(err)); |
usbd_errstr(err)); |
splx(s); |
splx(s); |
return; |
return; |
Line 568 cdce_init(void *xsc) |
|
Line 579 cdce_init(void *xsc) |
|
err = usbd_open_pipe(sc->cdce_data_iface, sc->cdce_bulkout_no, |
err = usbd_open_pipe(sc->cdce_data_iface, sc->cdce_bulkout_no, |
USBD_EXCLUSIVE_USE, &sc->cdce_bulkout_pipe); |
USBD_EXCLUSIVE_USE, &sc->cdce_bulkout_pipe); |
if (err) { |
if (err) { |
printf("%s: open tx pipe failed: %s\n", USBDEVNAME(sc->cdce_dev), |
printf("%s: open tx pipe failed: %s\n", device_xname(sc->cdce_dev), |
usbd_errstr(err)); |
usbd_errstr(err)); |
splx(s); |
splx(s); |
return; |
return; |
Line 597 cdce_newbuf(struct cdce_softc *sc, struc |
|
Line 608 cdce_newbuf(struct cdce_softc *sc, struc |
|
MGETHDR(m_new, M_DONTWAIT, MT_DATA); |
MGETHDR(m_new, M_DONTWAIT, MT_DATA); |
if (m_new == NULL) { |
if (m_new == NULL) { |
printf("%s: no memory for rx list " |
printf("%s: no memory for rx list " |
"-- packet dropped!\n", USBDEVNAME(sc->cdce_dev)); |
"-- packet dropped!\n", device_xname(sc->cdce_dev)); |
return (ENOBUFS); |
return (ENOBUFS); |
} |
} |
MCLGET(m_new, M_DONTWAIT); |
MCLGET(m_new, M_DONTWAIT); |
if (!(m_new->m_flags & M_EXT)) { |
if (!(m_new->m_flags & M_EXT)) { |
printf("%s: no memory for rx list " |
printf("%s: no memory for rx list " |
"-- packet dropped!\n", USBDEVNAME(sc->cdce_dev)); |
"-- packet dropped!\n", device_xname(sc->cdce_dev)); |
m_freem(m_new); |
m_freem(m_new); |
return (ENOBUFS); |
return (ENOBUFS); |
} |
} |
Line 688 cdce_rxeof(usbd_xfer_handle xfer, usbd_p |
|
Line 699 cdce_rxeof(usbd_xfer_handle xfer, usbd_p |
|
return; |
return; |
if (sc->cdce_rxeof_errors == 0) |
if (sc->cdce_rxeof_errors == 0) |
printf("%s: usb error on rx: %s\n", |
printf("%s: usb error on rx: %s\n", |
USBDEVNAME(sc->cdce_dev), usbd_errstr(status)); |
device_xname(sc->cdce_dev), usbd_errstr(status)); |
if (status == USBD_STALLED) |
if (status == USBD_STALLED) |
usbd_clear_endpoint_stall_async(sc->cdce_bulkin_pipe); |
usbd_clear_endpoint_stall_async(sc->cdce_bulkin_pipe); |
DELAY(sc->cdce_rxeof_errors * 10000); |
DELAY(sc->cdce_rxeof_errors * 10000); |
Line 728 cdce_rxeof(usbd_xfer_handle xfer, usbd_p |
|
Line 739 cdce_rxeof(usbd_xfer_handle xfer, usbd_p |
|
BPF_MTAP(ifp, m); |
BPF_MTAP(ifp, m); |
#endif |
#endif |
|
|
IF_INPUT(ifp, m); |
(*(ifp)->if_input)((ifp), (m)); |
|
|
done1: |
done1: |
splx(s); |
splx(s); |
Line 765 cdce_txeof(usbd_xfer_handle xfer, usbd_p |
|
Line 776 cdce_txeof(usbd_xfer_handle xfer, usbd_p |
|
return; |
return; |
} |
} |
ifp->if_oerrors++; |
ifp->if_oerrors++; |
printf("%s: usb error on tx: %s\n", USBDEVNAME(sc->cdce_dev), |
printf("%s: usb error on tx: %s\n", device_xname(sc->cdce_dev), |
usbd_errstr(status)); |
usbd_errstr(status)); |
if (status == USBD_STALLED) |
if (status == USBD_STALLED) |
usbd_clear_endpoint_stall_async(sc->cdce_bulkout_pipe); |
usbd_clear_endpoint_stall_async(sc->cdce_bulkout_pipe); |
splx(s); |
splx(s); |
Line 792 cdce_txeof(usbd_xfer_handle xfer, usbd_p |
|
Line 803 cdce_txeof(usbd_xfer_handle xfer, usbd_p |
|
} |
} |
|
|
int |
int |
cdce_activate(device_ptr_t self, enum devact act) |
cdce_activate(device_t self, enum devact act) |
{ |
{ |
struct cdce_softc *sc = device_private(self); |
struct cdce_softc *sc = device_private(self); |
|
|