This source file includes following definitions.
- umsm_match
- umsm_attach
- umsm_detach
- umsm_activate
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 #include <sys/param.h>
22 #include <sys/systm.h>
23 #include <sys/kernel.h>
24 #include <sys/device.h>
25 #include <sys/conf.h>
26 #include <sys/tty.h>
27
28 #include <dev/usb/usb.h>
29 #include <dev/usb/usbdi.h>
30 #include <dev/usb/usbdi_util.h>
31 #include <dev/usb/usbdevs.h>
32 #include <dev/usb/ucomvar.h>
33
34 #define UMSMBUFSZ 2048
35 #define UMSM_CONFIG_NO 0
36 #define UMSM_IFACE_NO 0
37
38 struct umsm_softc {
39 struct device sc_dev;
40 usbd_device_handle sc_udev;
41 usbd_interface_handle sc_iface;
42 struct device *sc_subdev;
43 u_char sc_dying;
44 };
45
46 struct ucom_methods umsm_methods = {
47 NULL,
48 NULL,
49 NULL,
50 NULL,
51 NULL,
52 NULL,
53 NULL,
54 NULL,
55 };
56
57 static const struct usb_devno umsm_devs[] = {
58 { USB_VENDOR_AIRPRIME, USB_PRODUCT_AIRPRIME_PC5220 },
59 { USB_VENDOR_DELL, USB_PRODUCT_DELL_W5500 },
60 { USB_VENDOR_KYOCERA2, USB_PRODUCT_KYOCERA2_KPC650 },
61 { USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_EXPRESSCARD },
62 { USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_MERLINV620 },
63 { USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_S720 },
64 { USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U720 },
65 { USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_XU870 },
66 { USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_ES620 },
67 { USB_VENDOR_QUALCOMM, USB_PRODUCT_QUALCOMM_MSM_HSDPA },
68 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_EM5625 },
69 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AIRCARD_580 },
70 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AIRCARD_595 },
71 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AIRCARD_875 },
72 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC5720 },
73 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC5725 },
74 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8755 },
75 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8755_2 },
76 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8765 },
77 { USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8775 },
78 };
79
80 int umsm_match(struct device *, void *, void *);
81 void umsm_attach(struct device *, struct device *, void *);
82 int umsm_detach(struct device *, int);
83 int umsm_activate(struct device *, enum devact);
84
85 struct cfdriver umsm_cd = {
86 NULL, "umsm", DV_DULL
87 };
88
89 const struct cfattach umsm_ca = {
90 sizeof(struct umsm_softc),
91 umsm_match,
92 umsm_attach,
93 umsm_detach,
94 umsm_activate,
95 };
96
97 int
98 umsm_match(struct device *parent, void *match, void *aux)
99 {
100 struct usb_attach_arg *uaa = aux;
101
102 if (uaa->iface != NULL)
103 return UMATCH_NONE;
104
105 return (usb_lookup(umsm_devs, uaa->vendor, uaa->product) != NULL) ?
106 UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
107 }
108
109 void
110 umsm_attach(struct device *parent, struct device *self, void *aux)
111 {
112 struct umsm_softc *sc = (struct umsm_softc *)self;
113 struct usb_attach_arg *uaa = aux;
114 struct ucom_attach_args uca;
115 usb_interface_descriptor_t *id;
116 usb_endpoint_descriptor_t *ed;
117 usbd_status error;
118 char *devinfop;
119 int i;
120
121 bzero(&uca, sizeof(uca));
122 sc->sc_udev = uaa->device;
123 devinfop = usbd_devinfo_alloc(uaa->device, 0);
124 printf("\n%s: %s\n", sc->sc_dev.dv_xname, devinfop);
125 usbd_devinfo_free(devinfop);
126
127 if (usbd_set_config_index(sc->sc_udev, UMSM_CONFIG_NO, 1) != 0) {
128 printf("%s: could not set configuration no\n",
129 sc->sc_dev.dv_xname);
130 sc->sc_dying = 1;
131 return;
132 }
133
134
135 error = usbd_device2interface_handle(sc->sc_udev, UMSM_IFACE_NO,
136 &sc->sc_iface);
137 if (error != 0) {
138 printf("%s: could not get interface handle\n",
139 sc->sc_dev.dv_xname);
140 sc->sc_dying = 1;
141 return;
142 }
143
144 id = usbd_get_interface_descriptor(sc->sc_iface);
145
146 uca.bulkin = uca.bulkout = -1;
147 for (i = 0; i < id->bNumEndpoints; i++) {
148 ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i);
149 if (ed == NULL) {
150 printf("%s: no endpoint descriptor found for %d\n",
151 sc->sc_dev.dv_xname, i);
152 sc->sc_dying = 1;
153 return;
154 }
155
156 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
157 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK)
158 uca.bulkin = ed->bEndpointAddress;
159 else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
160 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK)
161 uca.bulkout = ed->bEndpointAddress;
162 }
163 if (uca.bulkin == -1 || uca.bulkout == -1) {
164 printf("%s: missing endpoint\n", sc->sc_dev.dv_xname);
165 sc->sc_dying = 1;
166 return;
167 }
168
169
170 uca.ibufsize = UMSMBUFSZ;
171 uca.obufsize = UMSMBUFSZ;
172 uca.ibufsizepad = UMSMBUFSZ;
173 uca.opkthdrlen = 0;
174 uca.device = sc->sc_udev;
175 uca.iface = sc->sc_iface;
176 uca.methods = &umsm_methods;
177 uca.arg = sc;
178 uca.info = NULL;
179
180 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
181 &sc->sc_dev);
182
183 sc->sc_subdev = config_found_sm(self, &uca, ucomprint, ucomsubmatch);
184 }
185
186 int
187 umsm_detach(struct device *self, int flags)
188 {
189 struct umsm_softc *sc = (struct umsm_softc *)self;
190 int rv = 0;
191
192 sc->sc_dying = 1;
193 if (sc->sc_subdev != NULL) {
194 rv = config_detach(sc->sc_subdev, flags);
195 sc->sc_subdev = NULL;
196 }
197
198 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
199 &sc->sc_dev);
200
201 return (rv);
202 }
203
204 int
205 umsm_activate(struct device *self, enum devact act)
206 {
207 struct umsm_softc *sc = (struct umsm_softc *)self;
208 int rv = 0;
209
210 switch (act) {
211 case DVACT_ACTIVATE:
212 break;
213
214 case DVACT_DEACTIVATE:
215 if (sc->sc_subdev != NULL)
216 rv = config_deactivate(sc->sc_subdev);
217 sc->sc_dying = 1;
218 break;
219 }
220 return (rv);
221 }