Modem + Network in Xircom cards, and maybe others
Carlos Velasco
freebsd at newipnet.com
Wed May 5 04:37:46 PDT 2004
On 02/05/2004 at 22:24 Carlos Velasco wrote:
>On 02/05/2004 at 9:14 M. Warner Losh wrote:
>
>>: sio4: 118 more interrupt-level buffer overflows (total 118)
>>: sio4: 162 more interrupt-level buffer overflows (total 280)
>>
>>That may be due to the MFC interrupt issue that I talked about. But
>>it could be something else...
>
>I have tried playing with pccard_intr but it doesn't work.
>I'm reading about a patch for sio.c in the list, i don't know if it can
>helps into this I will try it in near future and see the results.
Well... this didn't work.
However I googled and found this:
http://lists.freebsd.org/pipermail/freebsd-bugs/2003-May/000687.html
Applying it solves problem for me.
Could we commit this in sio.c until GIANT solve work is done?
This is my complete patch (it works for me), including sio change and also
pccard 64k alignment:
diff -ru sys/dev/pccard/pccard.c sysnew/dev/pccard/pccard.c
--- sys/dev/pccard/pccard.c Wed Mar 17 17:50:38 2004
+++ sysnew/dev/pccard/pccard.c Sat May 1 09:47:57 2004
@@ -955,8 +955,8 @@
struct pccard_softc *sc = PCCARD_SOFTC(bus);
device_printf(bus, "<unknown card>");
- printf(" (manufacturer=0x%04x, product=0x%04x) at function %d\n",
- sc->card.manufacturer, sc->card.product, func->number);
+ printf(" (manufacturer=0x%04x, product=0x%04x, prodext=0x%02x) at
function %d\n",
+ sc->card.manufacturer, sc->card.product, sc->card.prodext,
func->number);
device_printf(bus, " CIS info: %s, %s, %s\n", sc->card.cis1_info[0],
sc->card.cis1_info[1], sc->card.cis1_info[2]);
return;
@@ -1075,6 +1075,7 @@
int passthrough = (device_get_parent(child) != dev);
int isdefault = (start == 0 && end == ~0UL && count == 1);
struct resource *r = NULL;
+ u_int align;
/* XXX I'm no longer sure this is right */
if (passthrough) {
@@ -1090,8 +1091,15 @@
if (rle == NULL || rle->res == NULL) {
/* Do we want this device to own it? */
/* XXX I think so, but that might be lame XXX */
+
+ /* force 64k page align */
+ if (type == SYS_RES_MEMORY)
+ align = (flags & ~RF_ALIGNMENT_MASK) |
+ rman_make_alignment_flags(64*1024);
+ else
+ align = flags;
r = bus_alloc_resource(dev, type, rid, start, end,
- count, flags /* XXX aligment? */);
+ count, align);
if (r == NULL)
goto bad;
resource_list_add(&dinfo->resources, type, *rid,
diff -ru sys/dev/pccard/pccard_cis.c sysnew/dev/pccard/pccard_cis.c
--- sys/dev/pccard/pccard_cis.c Mon Apr 12 20:56:34 2004
+++ sysnew/dev/pccard/pccard_cis.c Sat May 1 09:47:57 2004
@@ -96,6 +96,8 @@
state.pf = NULL;
+ state.card->mfc = 0;
+
tsleep(&state, 0, "pccard", hz);
if (pccard_scan_cis(sc->dev, pccard_parse_cis_tuple,
&state) == -1)
@@ -663,6 +665,7 @@
* up.
*/
state->gotmfc = 1;
+ state->card->mfc = 1;
break;
#ifdef PCCARDCISDEBUG
case CISTPL_DEVICE:
@@ -803,6 +806,42 @@
STAILQ_INSERT_TAIL(&state->card->pf_head, state->pf,
pf_list);
+ } else if (state->pf->function != PCCARD_FUNCTION_UNSPEC) {
+ /* We have a non-MFC compliant card, it puts more
+ * than 1 FUNCID in the CIS without LONGLINK.
+ * a) We put the functions in the list ala MFC.
+ * b) Copy last CFG entry for previous function,
+ * not sure if this is right, but usually works.
+ */
+ struct pccard_config_entry *cfe, *qcfe;
+ uint32_t ccr_base = state->pf->ccr_base;
+ uint32_t ccr_mask = state->pf->ccr_mask;
+
+ cfe = NULL;
+ STAILQ_FOREACH(qcfe, &state->pf->cfe_head, cfe_list) {
+ if (qcfe->number == state->pf->last_config_index) {
+ cfe = (struct pccard_config_entry *)
+ malloc(sizeof(*cfe), M_DEVBUF, M_NOWAIT);
+ *cfe = *qcfe;
+ break;
+ }
+ }
+
+ state->pf = malloc(sizeof(*state->pf), M_DEVBUF,
+ M_NOWAIT | M_ZERO);
+ state->pf->number = state->count++;
+ state->pf->last_config_index = cfe->number;
+ state->pf->ccr_base = ccr_base;
+ state->pf->ccr_mask = ccr_mask;
+
+ STAILQ_INIT(&state->pf->cfe_head);
+ if (cfe)
+ STAILQ_INSERT_TAIL(&state->pf->cfe_head,
+ cfe, cfe_list);
+
+ STAILQ_INSERT_TAIL(&state->card->pf_head, state->pf,
+ pf_list);
+
}
state->pf->function = pccard_tuple_read_1(tuple, 0);
diff -ru sys/dev/pccard/pccardvar.h sysnew/dev/pccard/pccardvar.h
--- sys/dev/pccard/pccardvar.h Sun Nov 2 20:18:19 2003
+++ sysnew/dev/pccard/pccardvar.h Sat May 1 09:47:57 2004
@@ -179,6 +179,7 @@
int32_t product;
#define PCMCIA_PRODUCT_INVALID -1
int16_t prodext;
+ int mfc;
uint16_t error;
#define PCMCIA_CIS_INVALID { NULL, NULL, NULL, NULL }
STAILQ_HEAD(, pccard_function) pf_head;
@@ -284,8 +285,9 @@
#define PCCARD_SPACE_IO 2
#define pccard_mfc(sc) \
- (STAILQ_FIRST(&(sc)->card.pf_head) && \
- STAILQ_NEXT(STAILQ_FIRST(&(sc)->card.pf_head),pf_list))
+ (sc->card.mfc)
+/* (STAILQ_FIRST(&(sc)->card.pf_head) && \
+ STAILQ_NEXT(STAILQ_FIRST(&(sc)->card.pf_head),pf_list)) */
#define pccard_io_alloc(pf, start, size, align, pciop) \
(pccard_chip_io_alloc((pf)->sc->pct, pf->sc->pch, (start), \
diff -ru sys/dev/sio/sio.c sysnew/dev/sio/sio.c
--- sys/dev/sio/sio.c Mon May 3 22:35:28 2004
+++ sysnew/dev/sio/sio.c Wed May 5 13:04:14 2004
@@ -2374,7 +2374,7 @@
* (about 3 ticks if input flow control is not used or not honoured,
* but a bit less for CS5-CS7 modes).
*/
- cp4ticks = speed / 10 / hz * 4;
+ cp4ticks = speed / 10 / hz * 40;
for (ibufsize = 128; ibufsize < cp4ticks;)
ibufsize <<= 1;
if (ibufsize == com->ibufsize) {
diff -ru sys/dev/xe/if_xe_pccard.c sysnew/dev/xe/if_xe_pccard.c
--- sys/dev/xe/if_xe_pccard.c Sun Apr 11 16:34:29 2004
+++ sysnew/dev/xe/if_xe_pccard.c Sat May 1 09:48:24 2004
@@ -402,6 +402,7 @@
const struct xe_pccard_product* xpp;
u_int16_t prodext;
+
DEVPRINTF(2, (dev, "pccard_product_match\n"));
xpp = (const struct xe_pccard_product*)ent;
@@ -409,6 +410,8 @@
if (xpp->prodext != prodext)
vpfmatch = 0;
+ else
+ vpfmatch++;
return (vpfmatch);
}
@@ -416,8 +419,19 @@
static int
xe_pccard_match(device_t dev)
{
+ int error = 0;
+ u_int32_t fcn = PCCARD_FUNCTION_UNSPEC;
const struct pccard_product *pp;
+ error = pccard_get_function(dev, &fcn);
+ if (error != 0)
+ return (error);
+ /*
+ * If not a network card, we are not the right driver.
+ */
+ if (fcn != PCCARD_FUNCTION_NETWORK)
+ return (ENXIO);
+
DEVPRINTF(2, (dev, "pccard_match\n"));
pp = (const struct pccard_product*)xe_pccard_products;
@@ -425,7 +439,6 @@
if ((pp = pccard_product_lookup(dev, pp,
sizeof(xe_pccard_products[0]), xe_pccard_product_match)) != NULL)
return (0);
-
return (EIO);
}
Regards,
Carlos Velasco
More information about the freebsd-mobile
mailing list