Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 11 Dec 2000 21:11:34 -0700
From:      Warner Losh <imp@village.org>
To:        YAMAMOTO Shigeru <shigeru@iij.ad.jp>
Cc:        freebsd-mobile@FreeBSD.ORG, freebsd-current@FreeBSD.ORG
Subject:   Re: patch for wi driver 
Message-ID:  <200012120411.VAA26651@harmony.village.org>
In-Reply-To: Your message of "Mon, 11 Dec 2000 15:55:32 %2B0900." <20001211155532C.shigeru@iij.ad.jp> 
References:  <20001211155532C.shigeru@iij.ad.jp>  

next in thread | previous in thread | raw e-mail | index | archive | help
[[ Followups to freebsd-mobile please ]]

In message <20001211155532C.shigeru@iij.ad.jp> YAMAMOTO Shigeru writes:
: I send a patch for wi driver.

Thank you yamamoto-san.  I'll have to see if this works with the prism 
II based boards that I have here that aren't supported by the an
driver.

: #Current wi driver has initialization and resource allocation mistakes.

I noticed that you fixed the bus_alloc_resource for the IOPORT to
always be 64 bytes long, aligned on a 64-byte boundary.  Are there
other mistakes as well?

: And this patch includes WEP support code for PrismII chip.
: Original WEP support code was writen by Onoe at NetBSD.
: But WEP support code does not work many PrismII based cards on FreeBSD.
: We need more hack.

Thanks for the update.  I can report that my lucent gold card still
works after these changes.  I have a few questions about the code.

: +#ifdef foo
:  	wi_cmd(sc, WI_CMD_INI, 0);
:  	DELAY(100000);
:  	wi_cmd(sc, WI_CMD_INI, 0);
: +#endif
:  	DELAY(100000);
: -#ifdef foo
:  	if (wi_cmd(sc, WI_CMD_INI, 0))
:  		device_printf(sc->dev, "init failed\n");
:  	CSR_WRITE_2(sc, WI_INT_EN, 0);
: @@ -633,7 +678,7 @@
:  
:  	/* Calibrate timer. */
:  	WI_SETVAL(WI_RID_TICK_TIME, 8);
: -#endif
: +
:  	return;
:  }
:  

If I'm reading this part of the patch collrectly, all wireset does is
put a delay 100000 (100ms) into the compiled in code.  Is that right?
Why did you do that?  Also, is there some reason that tsleep can't be
used instead (well, other than it being soon replaced with msleep)?

:  	sc->iobase = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
: -					0, ~0, 1, RF_ACTIVE);
: +				0, ~0, (1 << 6),
: +				rman_make_alignment_flags(1 << 6) | RF_ACTIVE);

I've run into this problem and made hacks to pccardd to only try
things on a "natural" boundary for the size of the i/o block.  This
likely is the right thing to do in the driver.

BTW, here are my changes to pccardd.  They also try to increase the
verbosity of the reports.  Down around the patch for lines 722(715)
you'll find where I do the check.  There's also some sprintf
reductions in these changes.  I've been running with them on my main
wireless server for a few weeks now and they seem OK, but I hesitate
to commit them.

Does this mean that all of your wireless cards now work with FreeBSD?
Or are there still some issues?

Thank you again for your efforts.

Warner


Index: cardd.c
===================================================================
RCS file: /home/imp/FreeBSD/CVS/src/usr.sbin/pccard/pccardd/cardd.c,v
retrieving revision 1.64
diff -u -r1.64 cardd.c
--- cardd.c	2000/10/20 13:08:18	1.64
+++ cardd.c	2000/11/19 04:42:00
@@ -42,7 +42,7 @@
 #include "cardd.h"
 
 static struct card_config *assign_driver(struct card *);
-static int		 assign_io(struct slot *);
+static char *		 assign_io(struct slot *);
 static int		 setup_slot(struct slot *);
 static void		 card_inserted(struct slot *);
 static void		 card_removed(struct slot *);
@@ -279,7 +279,7 @@
 card_inserted(struct slot *sp)
 {
 	struct card *cp;
-	int err;
+	char *reason;
 
 	usleep(pccard_init_sleep);
 	sp->cis = readcis(sp->fd);
@@ -362,27 +362,10 @@
 	}
 	if ((sp->config = assign_driver(cp)) == NULL) 
 		return;
-	if (err = assign_io(sp)) {
-		char *reason;
-
-		switch (err) {
-		case -1:
-			reason = "specified CIS was not found";
-			break;
-		case -2:
-			reason = "memory block allocation failed";
-			break;
-		case -3:
-			reason = "I/O block allocation failed";
-			break;
-		default:
-			reason = "Unknown";
-			break;
-		}
-                logmsg("Resource allocation failure for \"%s\"(\"%s\") "
-                       "[%s] [%s]; Reason %s\n",
-                    sp->cis->manuf, sp->cis->vers,
-                    sp->cis->add_info1, sp->cis->add_info2, reason);
+	if ((reason = assign_io(sp)) != NULL) {
+                logmsg("Resource allocation failure for \"%s\"(\"%s\"): "
+                    "%s\n", sp->cis->manuf, sp->cis->vers, reason);
+		free(reason);
 		return;
 	}
 
@@ -593,11 +576,12 @@
  *	assign_io - Allocate resources to slot matching the
  *	configuration index selected.
  */
-static int
+static char *
 assign_io(struct slot *sp)
 {
 	struct cis *cis;
 	struct cis_config *cisconf, *defconf;
+	char *reason;
 
 	cis = sp->cis;
 	defconf = cis->def_config;
@@ -617,9 +601,9 @@
 	}
 
 	if (cisconf == 0) {
-		logmsg("Config id %d not present in this card",
+		asprintf(&reason, "Config id %d not present in this card",
 		    sp->config->index);
-		return (-1);
+		return (reason);
 	}
 	sp->card_config = cisconf;
 
@@ -627,6 +611,7 @@
 	 * Found a matching configuration. Now look at the I/O, memory and IRQ
 	 * to create the desired parameters. Look at memory first.
 	 */
+	/* XXX Why check to see if the driver name is ed here? */
 	if (!(strncmp(sp->config->driver->name, "ed", 2) == 0
 		&& (sp->config->flags & 0x10))
 		&& (cisconf->memspace || (defconf && defconf->memspace))) {
@@ -646,8 +631,12 @@
 		 */
 		if (sp->mem.size && sp->mem.addr == 0) {
 			sp->mem.addr = alloc_memory(mp->length);
-			if (sp->mem.addr == 0)
-				return (-2);
+			if (sp->mem.addr == 0) {
+				asprintf(&reason,
+				    "Cannot allocate memory of %d bytes",
+				    mp->length);
+				return (reason);
+			}
 			sp->config->driver->mem = sp->mem.addr;
 		}
 		sp->mem.cardaddr = 0x4000;
@@ -713,7 +702,9 @@
 				char name[128];
 				int i, j, fd;
 
-				sprintf(name, CARD_DEVICE, 0); /* XXX */
+				j = -1;
+				/* XXX Assume unit 0 */
+				snprintf(name, sizeof(name), CARD_DEVICE, 0);
 				fd = open(name, O_RDWR);
  
 				res.type = SYS_RES_IOPORT;
@@ -722,8 +713,15 @@
 				for (i = 0; i < IOPORTS; i++) {
 					j = bit_fns(io_avail, IOPORTS, i,
 							sio->size, sio->size);
+					if (j == -1)
+						break;
+					if (j & (sio->size - 1))
+						continue;
 					res.min = j;
 					res.max = j + sio->size - 1;
+					if (debug_level > 1)
+						logmsg("Trying I/O 0x%x to 0x%x\n",
+						    res.min, res.max);
 					if (ioctl(fd, PIOCSRESOURCE, &res) < 0) {
 						perror("ioctl (PIOCSRESOURCE)");
 						exit(1);
@@ -732,7 +730,10 @@
 						break;
 				}
 				if (j < 0) {
-					return (-3);
+					asprintf(&reason,
+					    "Can't find I/O range of %d bytes",
+					    sio->size);
+					return (reason);
 				} else {
 					sio->addr = j;
 				}
@@ -770,7 +771,7 @@
 	}
 	sp->irq = sp->config->irq;
 	sp->flags |= IRQ_ASSIGNED;
-	return (0);
+	return (NULL);
 }
 
 /*


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-mobile" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200012120411.VAA26651>