11 { PL2303Vid, PL2303Did },
12 { PL2303Vid, PL2303DidRSAQ2 },
13 { PL2303Vid, PL2303DidDCU11 },
14 { PL2303Vid, PL2303DidRSAQ3 },
15 { PL2303Vid, PL2303DidPHAROS },
16 { PL2303Vid, PL2303DidALDIGA },
17 { PL2303Vid, PL2303DidMMX },
18 { PL2303Vid, PL2303DidGPRS },
19 { IODATAVid, IODATADid },
20 { IODATAVid, IODATADidRSAQ5 },
22 { ATENVid2, ATENDid },
23 { ELCOMVid, ELCOMDid },
24 { ELCOMVid, ELCOMDidUCSGT },
25 { ITEGNOVid, ITEGNODid },
26 { ITEGNOVid, ITEGNODid2080 },
27 { MA620Vid, MA620Did },
28 { RATOCVid, RATOCDid },
29 { TRIPPVid, TRIPPDid },
30 { RADIOSHACKVid,RADIOSHACKDid },
31 { DCU10Vid, DCU10Did },
32 { SITECOMVid, SITECOMDid },
33 { ALCATELVid, ALCATELDid },
34 { SAMSUNGVid, SAMSUNGDid },
35 { SIEMENSVid, SIEMENSDidSX1 },
36 { SIEMENSVid, SIEMENSDidX65 },
37 { SIEMENSVid, SIEMENSDidX75 },
38 { SIEMENSVid, SIEMENSDidEF81 },
39 { SYNTECHVid, SYNTECHDid },
40 { NOKIACA42Vid, NOKIACA42Did },
41 { CA42CA42Vid, CA42CA42Did },
42 { SAGEMVid, SAGEMDid },
43 { LEADTEKVid, LEADTEK9531Did },
44 { SPEEDDRAGONVid,SPEEDDRAGONDid },
45 { DATAPILOTU2Vid,DATAPILOTU2Did },
46 { BELKINVid, BELKINDid },
47 { ALCORVid, ALCORDid },
48 { WS002INVid, WS002INDid },
49 { COREGAVid, COREGADid },
50 { YCCABLEVid, YCCABLEDid },
51 { SUPERIALVid, SUPERIALDid },
52 { HPVid, HPLD220Did },
62 for(ip = plinfo; ip->vid != 0; ip++){
63 snprint(buf, sizeof buf, "vid %#06x did %#06x",
65 dsprint(2, "serial: %s %s\n", buf, info);
66 if(strstr(info, buf) != nil)
72 static void statusreader(void *u);
75 dumpbuf(uchar *buf, int bufsz)
79 for(i=0; i<bufsz; i++)
80 print("buf[%d]=%#ux ", i, buf[i]);
85 vendorread(Serialport *p, int val, int index, uchar *buf)
92 dsprint(2, "serial: vendorread val: 0x%x idx:%d buf:%p\n",
94 res = usbcmd(ser->dev, Rd2h | Rvendor | Rdev, VendorReadReq,
96 dsprint(2, "serial: vendorread res:%d\n", res);
101 vendorwrite(Serialport *p, int val, int index)
108 dsprint(2, "serial: vendorwrite val: 0x%x idx:%d\n", val, index);
109 res = usbcmd(ser->dev, Rh2d | Rvendor | Rdev, VendorWriteReq,
111 dsprint(2, "serial: vendorwrite res:%d\n", res);
115 /* BUG: I could probably read Dcr0 and set only the bits */
117 plmodemctl(Serialport *p, int set)
125 vendorwrite(p, Dcr0Idx|DcrSet, Dcr0Init);
130 if(ser->type == TypeHX)
131 vendorwrite(p, Dcr0Idx|DcrSet, Dcr0Init|Dcr0HwFcX);
133 vendorwrite(p, Dcr0Idx|DcrSet, Dcr0Init|Dcr0HwFcH);
138 plgetparam(Serialport *p)
140 uchar buf[ParamReqSz];
147 res = usbcmd(ser->dev, Rd2h | Rclass | Riface, GetLineReq,
148 0, 0, buf, sizeof buf);
152 * with the Pl9 interface it is not possible to set `1.5' as stop bits
159 fprint(2, "warning, stop bit set to 1.5 unsupported");
167 dsprint(2, "serial: getparam: ");
169 dumpbuf(buf, sizeof buf);
170 dsprint(2, "serial: getparam res: %d\n", res);
175 plsetparam(Serialport *p)
177 uchar buf[ParamReqSz];
187 else if(p->stop == 2)
188 buf[4] = 2; /* see comment in getparam */
192 dsprint(2, "serial: setparam: ");
194 dumpbuf(buf, sizeof buf);
195 res = usbcmd(ser->dev, Rh2d | Rclass | Riface, SetLineReq,
196 0, 0, buf, sizeof buf);
197 plmodemctl(p, p->mctl);
198 plgetparam(p); /* make sure our state corresponds */
200 dsprint(2, "serial: setparam res: %d\n", res);
219 /* linux driver says the release id is not always right */
221 heuristicid(ulong csp, ulong maxpkt)
223 if(Class(csp) == 0x02)
225 else if(maxpkt == 0x40)
227 else if(Class(csp) == 0x00 || Class(csp) == 0xFF)
230 fprint(2, "serial: chip unknown, setting to HX version\n");
236 plinit(Serialport *p)
240 ulong csp, maxpkt, dno;
244 buf = emallocz(VendorReqSz, 1);
245 dsprint(2, "plinit\n");
247 csp = ser->dev->usb->csp;
248 maxpkt = ser->dev->maxpkt;
249 dno = ser->dev->usb->dno;
251 if((ser->type = revid(dno)) == TypeUnk)
252 ser->type = heuristicid(csp, maxpkt);
254 dsprint(2, "serial: type %d\n", ser->type);
256 vendorread(p, 0x8484, 0, buf);
257 vendorwrite(p, 0x0404, 0);
258 vendorread(p, 0x8484, 0, buf);
259 vendorread(p, 0x8383, 0, buf);
260 vendorread(p, 0x8484, 0, buf);
261 vendorwrite(p, 0x0404, 1);
262 vendorread(p, 0x8484, 0, buf);
263 vendorread(p, 0x8383, 0, buf);
265 vendorwrite(p, Dcr0Idx|DcrSet, Dcr0Init);
266 vendorwrite(p, Dcr1Idx|DcrSet, Dcr1Init);
268 if(ser->type == TypeHX)
269 vendorwrite(p, Dcr2Idx|DcrSet, Dcr2InitX);
271 vendorwrite(p, Dcr2Idx|DcrSet, Dcr2InitH);
276 st = emallocz(255, 1);
279 serdumpst(p, st, 255);
282 /* p gets freed by closedev, the process has a reference */
284 proccreate(statusreader, p, 8*1024);
289 plsetbreak(Serialport *p, int val)
294 return usbcmd(ser->dev, Rh2d | Rclass | Riface,
295 (val != 0? BreakOn: BreakOff), val, 0, nil, 0);
299 plclearpipes(Serialport *p)
305 if(ser->type == TypeHX){
306 vendorwrite(p, PipeDSRst, 0);
307 vendorwrite(p, PipeUSRst, 0);
309 if(unstall(ser->dev, p->epout, Eout) < 0)
310 dprint(2, "disk: unstall epout: %r\n");
311 if(unstall(ser->dev, p->epin, Ein) < 0)
312 dprint(2, "disk: unstall epin: %r\n");
313 if(unstall(ser->dev, p->epintr, Ein) < 0)
314 dprint(2, "disk: unstall epintr: %r\n");
320 setctlline(Serialport *p, uchar val)
325 return usbcmd(ser->dev, Rh2d | Rclass | Riface, SetCtlReq,
330 composectl(Serialport *p)
333 p->ctlstate |= CtlRTS;
335 p->ctlstate &= ~CtlRTS;
337 p->ctlstate |= CtlDTR;
339 p->ctlstate &= ~CtlDTR;
343 plsendlines(Serialport *p)
347 dsprint(2, "serial: sendlines: %#2.2x\n", p->ctlstate);
349 res = setctlline(p, p->ctlstate);
350 dsprint(2, "serial: sendlines res: %d\n", res);
355 plreadstatus(Serialport *p)
359 uchar buf[VendorReqSz];
365 dsprint(2, "serial: reading from interrupt\n");
366 dfd = p->epintr->dfd;
369 nr = read(dfd, buf, sizeof buf);
371 snprint(err, sizeof err, "%r");
372 dsprint(2, "serial: interrupt read %d %r\n", nr);
374 if(nr < 0 && strstr(err, "timed out") == nil){
375 dsprint(2, "serial: need to recover, status read %d %r\n", nr);
376 if(serialrecover(ser, nil, nil, err) < 0){
382 dsprint(2, "serial: reading status: %r");
383 else if(nr >= sizeof buf - 1){
384 p->dcd = buf[8] & DcdStatus;
385 p->dsr = buf[8] & DsrStatus;
386 p->cts = buf[8] & BreakerrStatus;
387 p->ring = buf[8] & RingStatus;
388 p->cts = buf[8] & CtsStatus;
389 if(buf[8] & FrerrStatus)
391 if(buf[8] & ParerrStatus)
393 if(buf[8] & OvererrStatus)
396 dsprint(2, "serial: bad status read %d\n", nr);
397 dsprint(2, "serial: finished read from interrupt %d\n", nr);
403 statusreader(void *u)
410 threadsetname("statusreaderproc");
411 while(plreadstatus(p) >= 0)
413 fprint(2, "serial: statusreader exiting\n");
418 * Maximum number of bytes transferred per frame
419 * The output buffer size cannot be increased due to the size encoding
423 plseteps(Serialport *p)
425 devctl(p->epin, "maxpkt 256");
426 devctl(p->epout, "maxpkt 256");
432 .getparam = plgetparam,
433 .setparam = plsetparam,
434 .clearpipes = plclearpipes,
435 .sendlines = plsendlines,
436 .modemctl = plmodemctl,
437 .setbreak = plsetbreak,