Subject: Re: New maple code
To: Marcus Comstedt <marcus@idonex.se>
From: Jay Krell <jay.krell@cornell.edu>
List: port-dreamcast
Date: 05/26/2001 16:40:25
> char fn[16];
> if(subunit)
> sprintf(fn+11, "%d", subunit);
> else
> sprintf(fn, "/dev/maple%c", 'A'+port);
How about something more like:
#define DEV_MAPLE "/dev/maple"
/* sizeof(x) * CHAR_BIT is an overestimate for the number of chars needed to
hold something as a string
sizeof("x") is 2, + 1 is for the "port".
*/
char fn[sizeof(DEV_MAPLE) + 1 + sizeof(MAPLE_PORTS) * CHAR_BIT] =
DEV_MAPLE;
for(port = 0; port < MAPLE_PORTS; port++) {
fn[sizeof(DEV_MAPLE) - 1] = 'A' + port;
fn[sizeof(DEV_MAPLE)] = 0;
for(subunit = 0; subunit < MAPLE_SUBUNITS; subunit++) {
if(subunit)
sprintf(fn + sizeof(DEV_MAPLE), "%d", subunit);
It should be a bit faster.
And NetBSD doesn't have a function like "_itoa" to do the %d with a less
general function than sprintf? And NetBSD doesn't have something like
"_snprintf" to ensure no buffer overflow (though I realize it isn't really
needed here, where the data being printed is well known and a large enough
buffer is supplied)?
I guess for sample code, not kernel code, it isn't worth it..
- Jay
-----Original Message-----
From: Marcus Comstedt <marcus@idonex.se>
To: port-dreamcast@netbsd.org <port-dreamcast@netbsd.org>
Date: Saturday, May 26, 2001 12:19 PM
Subject: New maple code
>
>Ok, I have now checked in the new maple autoconf code.
>
>Since Jason never did give me the rundown of the correct "NetBSD way"
>of doing it, I had to improvise. The specific devices (mkbd and the
>upcoming mmc (memorycard) driver) basically work like before, except
>that multiple drivers can attach to the same unit (one per function
>code). The main change is that you can open the bus device itself as
>a raw channel to a maple unit of choice. The minor device number is
>used to select the physical location of the unit you want to talk to
>(port * 8 + subunit), and MAKEDEV has been updated to create device
>nodes like /dev/mapleB2 for the second subunit slot on the unit
>plugged into port B. The only operation that can be done on the raw
>maple device right now is the MAPLEIO_GDEVINFO ioctl, which gets the
>devinfo struct. Here's an example program that uses it:
>
>
>---8<---
>#include <stdio.h>
>#include <fcntl.h>
>#include <errno.h>
>#include <dreamcast/dev/maple/mapleio.h>
>
>void describe_unit(char *name, struct maple_devinfo *info)
>{
> printf("%s: %.*s\n", name,
> (int)sizeof(info->di_product_name), info->di_product_name);
>}
>
>int main()
>{
> int port;
> int subunit;
> char fn[16];
> int fd;
> struct maple_devinfo devinfo;
>
> for(port = 0; port < MAPLE_PORTS; port++)
> for(subunit = 0; subunit < MAPLE_SUBUNITS; subunit++) {
> if(subunit)
> sprintf(fn+11, "%d", subunit);
> else
> sprintf(fn, "/dev/maple%c", 'A'+port);
> if((fd = open(fn, O_RDONLY))>=0) {
> if(ioctl(fd, MAPLEIO_GDEVINFO, &devinfo)>=0)
> describe_unit(fn+5, &devinfo);
> else
> perror(fn);
> close(fd);
> } else if(errno != ENOENT && errno != ENXIO)
> perror(fn);
> }
> return 0;
>}
>---8<---
>
>(I haven't added the header to the installed set yet, so you'll have
> to use -I/something/appropriate.)
>
>As I said, specific devices still work the same, which means that
>minor device numbers are allocated sequentially as needed. I do
>intend to add an ioctl to query the physical location though.
>
>
> // Marcus
>
>
>