Subject: Re: New maple code
To: Marcus Comstedt <>
From: Jay Krell <>
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] =

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++) {
            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 <>
To: <>
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:
>#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;
>(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