Fix ISA autoconfusion
isa(4) is an indirect bus, which means that drivers that attach to it need to provide an xxxprobe() method instead of an xxxmatch() method. The critical difference is xxxprobe() is given a device softc for the second argument, whereas a xxxmatch() is given the cfdata as the second argument. However, a number of our ISA device drivers treat the second argument as a cfdata instead of a softc. Diff below addresses this. (Only complication: unlike isa(4), isapnp(4) is a direct bus, and if_we.c used the same probe/match code for both.) Does this look right? (Compile tested on i386, but I don't have any ISA hardware, and I'm not having any luck with qemu's "isapc" machine at the moment...) Index: if_lc_isa.c === RCS file: /home/mdempsky/anoncvs/cvs/src/sys/dev/isa/if_lc_isa.c,v retrieving revision 1.8 diff -u -p -r1.8 if_lc_isa.c --- if_lc_isa.c 10 Aug 2009 22:08:04 - 1.8 +++ if_lc_isa.c 14 Jun 2011 05:38:30 - @@ -182,7 +182,7 @@ lemac_isa_probe(parent, match, aux) void *aux; { struct isa_attach_args *ia = aux; - struct cfdata *cf = match; + struct cfdata *cf = ((struct device *)match)->dv_cfdata; struct lemac_softc sc; snprintf(sc.sc_dv.dv_xname, sizeof sc.sc_dv.dv_xname, "%s%d", Index: if_we.c === RCS file: /home/mdempsky/anoncvs/cvs/src/sys/dev/isa/if_we.c,v retrieving revision 1.20 diff -u -p -r1.20 if_we.c --- if_we.c 26 Jun 2008 05:42:16 - 1.20 +++ if_we.c 14 Jun 2011 05:41:34 - @@ -110,6 +110,7 @@ struct we_softc { }; intwe_probe(struct device *, void *, void *); +intwe_match(struct device *, void *, void *); void we_attach(struct device *, struct device *, void *); struct cfattach we_isa_ca = { @@ -118,7 +119,7 @@ struct cfattach we_isa_ca = { #if NWE_ISAPNP struct cfattach we_isapnp_ca = { - sizeof(struct we_softc), we_probe, we_attach + sizeof(struct we_softc), we_match, we_attach }; #endif /* NWE_ISAPNP */ @@ -185,6 +186,14 @@ do { \ int we_probe(struct device *parent, void *match, void *aux) +{ + struct cfdata *cf = ((struct device *)match)->dv_cfdata; + + return (we_match(parent, cf, aux)); +} + +int +we_match(struct device *parent, void *match, void *aux) { struct isa_attach_args *ia = aux; struct cfdata *cf = match; Index: radiotrack2.c === RCS file: /home/mdempsky/anoncvs/cvs/src/sys/dev/isa/radiotrack2.c,v retrieving revision 1.3 diff -u -p -r1.3 radiotrack2.c --- radiotrack2.c 7 Jan 2002 18:32:19 - 1.3 +++ radiotrack2.c 14 Jun 2011 05:34:52 - @@ -127,7 +127,7 @@ rtii_probe(struct device *parent, void * struct isa_attach_args *ia = aux; bus_space_tag_t iot = ia->ia_iot; bus_space_handle_t ioh; - struct cfdata *cf = match; + struct cfdata *cf = ((struct device *)match)->dv_cfdata; int iosize = 1, iobase = ia->ia_iobase; if (!RTII_BASE_VALID(iobase)) { Index: sf16fmr2.c === RCS file: /home/mdempsky/anoncvs/cvs/src/sys/dev/isa/sf16fmr2.c,v retrieving revision 1.6 diff -u -p -r1.6 sf16fmr2.c --- sf16fmr2.c 15 Oct 2002 15:00:11 - 1.6 +++ sf16fmr2.c 14 Jun 2011 05:34:32 - @@ -140,7 +140,7 @@ sf2r_probe(struct device *parent, void * struct isa_attach_args *ia = aux; bus_space_tag_t iot = ia->ia_iot; bus_space_handle_t ioh; - struct cfdata *cf = match; + struct cfdata *cf = ((struct device *)match)->dv_cfdata; int iosize = 1, iobase = ia->ia_iobase; if (!SF16FMR2_BASE_VALID(iobase)) { Index: wdc_isa.c === RCS file: /home/mdempsky/anoncvs/cvs/src/sys/dev/isa/wdc_isa.c,v retrieving revision 1.14 diff -u -p -r1.14 wdc_isa.c --- wdc_isa.c 9 May 2011 22:33:54 - 1.14 +++ wdc_isa.c 14 Jun 2011 05:34:05 - @@ -83,7 +83,7 @@ wdc_isa_probe(struct device *parent, voi { struct channel_softc ch; struct isa_attach_args *ia = aux; - struct cfdata *cf = match; + struct cfdata *cf = ((struct device *)match)->dv_cfdata; int result = 0; bzero(&ch, sizeof ch);
smarter query for hds preferred ownership
this is based on the solaris code. its a lot less arbitrary than the stupid linux code. if this works i'll add back the printing of the physical path, it can be useful when debugging wiring issues. cheers, dlg Index: mpath_hds.c === RCS file: /cvs/src/sys/scsi/mpath_hds.c,v retrieving revision 1.2 diff -u -p -r1.2 mpath_hds.c --- mpath_hds.c 28 Apr 2011 10:43:36 - 1.2 +++ mpath_hds.c 14 Jun 2011 05:34:00 - @@ -37,6 +37,17 @@ #include #include +#define HDS_VPD0xe0 + +struct hds_vpd { +struct scsi_vpd_hdrhdr; /* HDS_VPD */ + u_int8_tstate; +#define HDS_VPD_VALID 0x80 +#define HDS_VPD_PREFERRED 0x40 + + /* followed by lots of unknown stuff */ +}; + struct hds_softc { struct device sc_dev; struct mpath_path sc_path; @@ -80,7 +91,7 @@ struct hds_device { char *product; }; -inthds_priority(struct hds_softc *); +inthds_preferred(struct scsi_link *, int *); struct hds_device hds_devices[] = { /* " vendor " " device " */ @@ -94,8 +105,9 @@ hds_match(struct device *parent, void *m { struct scsi_attach_args *sa = aux; struct scsi_inquiry_data *inq = sa->sa_inqbuf; + struct scsi_link *link = sa->sa_sc_link; struct hds_device *s; - int i; + int i, preferred; if (mpath_path_probe(sa->sa_sc_link) != 0) return (0); @@ -104,8 +116,11 @@ hds_match(struct device *parent, void *m s = &hds_devices[i]; if (bcmp(s->vendor, inq->vendor, strlen(s->vendor)) == 0 && - bcmp(s->product, inq->product, strlen(s->product)) == 0) - return (3); + bcmp(s->product, inq->product, strlen(s->product)) == 0 && + hds_preferred(link, &preferred) == 0) { + /* match above sym(4) */ + return (4); + } } return (0); @@ -128,7 +143,7 @@ hds_attach(struct device *parent, struct sc->sc_path.p_link = link; sc->sc_path.p_ops = &hds_mpath_ops; - if (hds_priority(sc) != 0) + if (hds_preferred(link, &sc->sc_active) != 0) return; if (!sc->sc_active) @@ -190,68 +205,26 @@ hds_mpath_offline(struct scsi_link *link } int -hds_priority(struct hds_softc *sc) +hds_preferred(struct scsi_link *link, int *preferred) { - u_int8_t *buffer; - struct scsi_inquiry *cdb; - struct scsi_xfer *xs; - size_t length; - u_int8_t ldev[9]; - u_int8_t ctrl; - u_int8_t port; - int p, c; + struct hds_vpd *pg; int error; - length = MIN(sc->sc_path.p_link->inqdata.additional_length + 5, 255); - if (length < 51) - return (EIO); - - buffer = dma_alloc(length, PR_WAITOK); - - xs = scsi_xs_get(sc->sc_path.p_link, scsi_autoconf); - if (xs == NULL) { - error = EBUSY; - goto done; - } - - cdb = (struct scsi_inquiry *)xs->cmd; - cdb->opcode = INQUIRY; - _lto2b(length, cdb->length); - - xs->cmdlen = sizeof(*cdb); - xs->flags |= SCSI_DATA_IN; - xs->data = buffer; - xs->datalen = length; + pg = dma_alloc(sizeof(*pg), PR_WAITOK); - error = scsi_xs_sync(xs); - scsi_xs_put(xs); - - if (error != 0) + error = scsi_inquire_vpd(link, pg, sizeof(*pg), HDS_VPD, scsi_autoconf); + if (error) goto done; - /* XXX magical */ - bzero(ldev, sizeof(ldev)); - scsi_strvis(ldev, buffer + 44, 4); - ctrl = buffer[49]; - port = buffer[50]; - - if (strlen(ldev) > 4 || ldev[3] < '0' || ldev[3] > 'F' || - ctrl < '0' || ctrl > '9' || - port < 'A' || port > 'B') { - error = EIO; + if (_2btol(pg->hdr.page_length) < sizeof(pg->state) || +!ISSET(pg->state, HDS_VPD_VALID)) { + error = ENXIO; goto done; } - c = ctrl - '0'; - p = port - 'A'; - if ((c & 0x1) == (p & 0x1)) - sc->sc_active = 1; - - printf("%s: ldev %s, controller %c, port %c\n", DEVNAME(sc), ldev, - ctrl, port); + *preferred = ISSET(pg->state, HDS_VPD_PREFERRED); - error = 0; done: - dma_free(buffer, length); + dma_free(pg, sizeof(*pg)); return (error); }
Re: Synaptics touchpad
> I find the mouse emulation code for synaptics touch pads in your patch > really weird. I've tried to understand what it does, and why it > behaves badly for me on the first tap (move the pointer in the upper > right direction every time), but I fail to understand the logic. your change makes the problem worse on 2 laptops (samsung series 9 and thinkpad x220), where the cursor now jumps to the lower left after every movement. these seem to be due to events that come through after removing all the fingers from the touchpad that need to be ignored. i checked linux and they also ignore these events: http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=4f56ce929cab45a3a6e1a81700da52bb9bdbfc0f this also adds support for "clickpads" where there is only one physical button and it's the entire trackpad that moves down, which both of those laptops have. without this change, the click gets ignored. --- pms.c.new Mon Jun 13 16:26:39 2011 +++ pms.c Mon Jun 13 20:06:59 2011 @@ -799,7 +799,9 @@ syn->wsmode = WSMOUSE_COMPAT; syn->count = 0; - printf("%s: Synaptics touchpad, firmware %d.%d\n", DEVNAME(sc), + printf("%s: Synaptics %s, firmware %d.%d\n", DEVNAME(sc), + (syn->capabilities & SYNAPTICS_EXT_CAP_CLICKPAD ? + "clickpad" : "touchpad"), SYNAPTICS_ID_MAJOR(syn->identify), SYNAPTICS_ID_MINOR(syn->identify)); } @@ -882,8 +884,11 @@ buttons |= ((sc->packet[0] & 0x02) & (sc->packet[3] & 0x02)) ? WSMOUSE_BUTTON(3) : 0; - if (syn->capabilities & SYNAPTICS_CAP_MIDDLE_BUTTON) { + if (syn->ext_capabilities & SYNAPTICS_EXT_CAP_CLICKPAD) { buttons |= ((sc->packet[0] & 0x01) ^ (sc->packet[3] & 0x01)) ? + WSMOUSE_BUTTON(1) : 0; + } else if (syn->capabilities & SYNAPTICS_CAP_MIDDLE_BUTTON) { + buttons |= ((sc->packet[0] & 0x01) ^ (sc->packet[3] & 0x01)) ? WSMOUSE_BUTTON(2) : 0; } @@ -906,6 +911,14 @@ y &= ~0x0f; } + /* ignore final events that happen when removing all fingers */ + if (x <= 1 && !z) { + x = syn->old_x; + y = syn->old_y; + w = 0; + buttons = 0; + } + if (syn->wsmode == WSMOUSE_NATIVE) { wsmouse_input(sc->sc_wsmousedev, buttons, x, y, z, w, WSMOUSE_INPUT_ABSOLUTE_X | WSMOUSE_INPUT_ABSOLUTE_Y | @@ -925,10 +938,11 @@ if (dx || dy || buttons != syn->old_buttons) wsmouse_input(sc->sc_wsmousedev, buttons, dx, dy, 0, 0, WSMOUSE_INPUT_DELTA); - syn->old_x = x; - syn->old_y = y; syn->old_buttons = buttons; } + + syn->old_x = x; + syn->old_y = y; } void
TV LCD - Cámaras Reflex y Semi Pro
Disponibilidad inmedita / Local a la calle / Últimas unidades TV LCD Samsung 40 Pulgadas Modelo UN40D6450 Lentes 3D De regalo USD 2100 USD 1480 Canon EOS 60D Body Tipo réflex, objetivos intercambiables / Sensor CMOS de 18,00 MP efectivos / Tamaño sensor 22,30 x 14,90 mm / Montura Canon EF-S - / Factor de multiplicación 1,60x / Pantalla TFT de 3,00 pulgadas Canon EOS 60D Kit 18-105 USD 1820 USD 1600 Nikon D7000 Body Tipo réflex, objetivos intercambiables / Sensor CMOS de 16,20 MP efectivos / Tamaño sensor 23,60 x 15,60 mm / Montura Nikon -/ Factor de multiplicación 1,50x / Pantalla TFT de 3,00 pulgadas Nikon D7000 Kit 18-105 USD 1980 USD 375