Driver for PCCARD / PCMCIA
Jacqueline P
jackie7691 at yahoo.com.mx
Wed Apr 5 11:48:12 UTC 2006
Hello Warner,
thanks for your help. Now I've created a skeleton driver (see above).
How is the resource management (mapping) done ?
Furthermore I'm missing my debug output when I first KLDload the driver and then insert the pccard. Which process gets the output ?
#include <sys/types.h>
#include <sys/module.h>
#include <sys/systm.h> // uprintf
#include <sys/errno.h>
#include <sys/param.h> // types used in kernel.h
#include <sys/kernel.h> // types used in module initialization
#include <sys/conf.h> // cdevsw structure
#include <sys/stat.h> // Permision flags
#include <sys/bus.h>
#include <machine/bus.h>
#include <sys/rman.h>
#include <machine/resource.h>
#include <dev/pccard/pccardvar.h>
#include <dev/pccard/pccard_cis.h>
#include "pccarddevs.h"
#include "cm4040_cs.h"
#define DEBUG_LEVEL_COM 1
#define DEBUG_LEVEL_INFO 2
#define PCCARD_DEBUG DEBUG_LEVEL_COM | DEBUG_LEVEL_INFO
#ifdef PCCARD_DEBUG
#define DEBUG(n, args...) if ((PCCARD_DEBUG) & (n)) uprintf(args)
#else
#define DEBUG(n, args...)
#endif
//
// Supported products
//
static const struct pccard_product cmx_pccard_products[] = {
PCMCIA_CARD(OMNIKEY, CARDMAN_4040, 0),
{ NULL }
};
//
// Bus Front End Functions
//
static int cmx_pccard_match(device_t);
static int cmx_pccard_probe(device_t);
static int cmx_pccard_attach(device_t);
static int cmx_pccard_detach(device_t);
static device_method_t cmx_pccard_methods[] = {
// Device interface
// DEVMETHOD(device_probe,pccard_compat_probe),
// DEVMETHOD(device_attach, pccard_compat_attach),
// DEVMETHOD(device_detach, cmx_pccard_detach),
DEVMETHOD(device_probe,cmx_pccard_probe),
DEVMETHOD(device_attach, cmx_pccard_attach),
DEVMETHOD(device_detach, cmx_pccard_detach),
// Card interface
// DEVMETHOD(card_compat_match, cmx_pccard_match),
// DEVMETHOD(card_compat_probe,cmx_pccard_probe),
// DEVMETHOD(card_compat_attach, cmx_pccard_attach),
{ 0, 0 }
};
//
// Private data
//
struct cmx_softc {
// struct ifmedia ifmedia;
device_t dev;
//struct resource *ioport;
//int ioport_rid;
//bus_space_tag_t bst;
//bus_space_handle_t bsh;
};
static driver_t cmx_pccard_driver = {
"cmx",
cmx_pccard_methods,
sizeof(struct cmx_softc),
};
static int cmx_loader(struct module *m, int reason, void *arg);
devclass_t cmx_devclass;
//DRIVER_MODULE(ex, pccard, ex_pccard_driver, ex_devclass, 0, 0);
DRIVER_MODULE(cmx, pccard, cmx_pccard_driver, cmx_devclass, cmx_loader, 0);
//
// Character driver function prototypes
//
static d_open_t cmx_open;
static d_close_t cmx_close;
static d_read_t cmx_read;
static d_write_t cmx_write;
//
// Character device entry points
//
static struct cdevsw cmx_cdevsw =
{
.d_version = D_VERSION,
.d_open = cmx_open,
.d_close = cmx_close,
.d_read = cmx_read,
.d_write = cmx_write,
.d_name = MODULE_NAME
};
//
// Variables
//
static dev_t sdev;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cmx_pccard_match
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static int cmx_pccard_match(device_t dev)
{
const struct pccard_product *pp;
int err = EIO;
DEBUG(DEBUG_LEVEL_COM,"cmx_pccard_match ->\n");
if ((pp = pccard_product_lookup(dev, cmx_pccard_products,
sizeof(cmx_pccard_products[0]), NULL)) != NULL)
{
if (pp->pp_name != NULL)
device_set_desc(dev, pp->pp_name);
DEBUG(DEBUG_LEVEL_INFO,"pp->pp_name = %s\n", pp->pp_name);
err = 0;
}
DEBUG(DEBUG_LEVEL_COM,"cmx_pccard_match <- returned 0x%x\n", err);
return err;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cmx_pccard_probe
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static int cmx_pccard_probe(device_t dev)
{
u_int iobase;
u_int count;
u_int irq;
int err = 0;
DEBUG(DEBUG_LEVEL_COM,"cmx_pccard_probe ->\n");
iobase = bus_get_resource_start(dev, SYS_RES_IOPORT, 0);
count = bus_get_resource_count(dev, SYS_RES_IOPORT, 0);
DEBUG(DEBUG_LEVEL_INFO,"iobase = 0x%x\n", iobase);
DEBUG(DEBUG_LEVEL_INFO,"count = 0x%x\n", count);
/*
if (!iobase) {
printf("ex: no iobase?\n");
return(ENXIO);
}
if (bootverbose)
printf("ex: ex_pccard_probe() found card at 0x%03x\n", iobase);
irq = bus_get_resource_start(dev, SYS_RES_IRQ, 0);
if (irq == 0) {
printf("ex: invalid IRQ.\n");
return(ENXIO);
}
*/
DEBUG(DEBUG_LEVEL_COM,"cmx_pccard_probe <- returned 0x%x\n", err);
return(err);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cmx_pccard_attach
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static int cmx_pccard_attach(device_t dev)
{
struct cmx_softc * sc = device_get_softc(dev);
int err = 0;
DEBUG(DEBUG_LEVEL_COM,"cmx_pccard_attach ->\n");
/*
sc->dev = dev;
sc->ioport_rid = 0;
sc->irq_rid = 0;
if ((error = ex_alloc_resources(dev)) != 0) {
device_printf(dev, "ex_alloc_resources() failed!\n");
goto bad;
}
// Try to get the ethernet address from the chip, then the CIS
ex_get_address(sc, ether_addr);
if (!ex_pccard_enet_ok(ether_addr))
pccard_get_ether(dev, ether_addr);
if (!ex_pccard_enet_ok(ether_addr))
ex_pccard_get_silicom_mac(dev, ether_addr);
if (!ex_pccard_enet_ok(ether_addr)) {
device_printf(dev, "No NIC address found.\n");
error = ENXIO;
goto bad;
}
bcopy(ether_addr, sc->arpcom.ac_enaddr, ETHER_ADDR_LEN);
if ((error = ex_attach(dev)) != 0) {
device_printf(dev, "ex_attach() failed!\n");
goto bad;
}
error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET,
ex_intr, (void *)sc, &sc->ih);
if (error) {
device_printf(dev, "bus_setup_intr() failed!\n");
goto bad;
}
*/
err = 0;
DEBUG(DEBUG_LEVEL_COM,"cmx_pccard_attach <- returned 0x%x\n", err);
return (err);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cmx_detach
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int cmx_pccard_detach(device_t dev)
{
int err = 0;
struct cmx_softc *sc;
DEBUG(DEBUG_LEVEL_COM,"cmx_detach ->\n");
// ex_release_resources(dev);
DEBUG(DEBUG_LEVEL_COM,"cmx_detach <- returned 0x%x\n", err);
return (err);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cmx_loader
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static int cmx_loader(struct module *m, int reason, void *arg)
{
int err = 0;
switch (reason)
{
case MOD_LOAD:
sdev = make_dev(& cmx_cdevsw,
0, // Minor
UID_ROOT,
GID_WHEEL,
S_IRUSR | S_IWUSR,
DEVICE_NAME);
DEBUG(DEBUG_LEVEL_COM,"Driver %s loaded\n",MODULE_NAME);
break;
case MOD_UNLOAD:
destroy_dev(sdev);
DEBUG(DEBUG_LEVEL_COM,"Driver %s unloaded\n",MODULE_NAME);
break;
default:
err = EINVAL;
break;
}
return err;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cmx_open
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static int cmx_open(struct cdev *dev, int oflags, int devtype, struct thread *p)
{
int err = 0;
DEBUG(DEBUG_LEVEL_COM,"cmx_open ->\n");
DEBUG(DEBUG_LEVEL_COM,"cmx_open <- returned 0x%x\n", err);
return err;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cmx_close
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static int cmx_close(struct cdev *dev, int fflag, int devtype, struct thread *p)
{
int err = 0;
DEBUG(DEBUG_LEVEL_COM,"cmx_close ->\n");
DEBUG(DEBUG_LEVEL_COM,"cmx_close <- returned 0x%x\n", err);
return err;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cmx_read
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static int cmx_read(struct cdev *dev, struct uio *uio, int ioflag)
{
int err = 0;
DEBUG(DEBUG_LEVEL_COM,"cmx_read ->\n");
DEBUG(DEBUG_LEVEL_COM,"cmx_read <- returned 0x%x\n", err);
return err;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// cmx_write
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static int cmx_write(struct cdev *dev, struct uio *uio, int ioflag)
{
int err = 0;
DEBUG(DEBUG_LEVEL_COM,"cmx_write ->\n");
DEBUG(DEBUG_LEVEL_COM,"cmx_write <- returned 0x%x\n", err);
return err;
}
//DEV_MODULE(CM4040, cmx_loader, NULL);
---------------------------------
Do You Yahoo!? La mejor conexión a Internet y 2GB extra a tu correo por $100 al mes. http://net.yahoo.com.mx
More information about the freebsd-drivers
mailing list