The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/pci/nfsmb.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 #include <sys/cdefs.h>
    2 __FBSDID("$FreeBSD$");
    3 
    4 #include <sys/param.h>
    5 #include <sys/bus.h>
    6 #include <sys/kernel.h>
    7 #include <sys/lock.h>
    8 #include <sys/module.h>
    9 #include <sys/mutex.h>
   10 #include <sys/systm.h>
   11 
   12 #include <machine/bus.h>
   13 #include <machine/resource.h>
   14 #include <sys/rman.h>
   15 
   16 #include <dev/pci/pcivar.h>
   17 #include <dev/pci/pcireg.h>
   18 
   19 #include <dev/smbus/smbconf.h>
   20 #include "smbus_if.h"
   21 
   22 #define NFSMB_DEBUG(x)  if (nfsmb_debug) (x)
   23 
   24 #ifdef DEBUG
   25 static int nfsmb_debug = 1;
   26 #else
   27 static int nfsmb_debug = 0;
   28 #endif
   29 
   30 /* NVIDIA nForce2/3/4 MCP */
   31 #define NFSMB_VENDORID_NVIDIA           0x10de
   32 #define NFSMB_DEVICEID_NF2_SMB          0x0064
   33 #define NFSMB_DEVICEID_NF2_ULTRA_SMB    0x0084
   34 #define NFSMB_DEVICEID_NF3_PRO150_SMB   0x00d4
   35 #define NFSMB_DEVICEID_NF3_250GB_SMB    0x00e4
   36 #define NFSMB_DEVICEID_NF4_SMB          0x0052
   37 #define NFSMB_DEVICEID_NF4_04_SMB       0x0034
   38 #define NFSMB_DEVICEID_NF4_51_SMB       0x0264
   39 #define NFSMB_DEVICEID_NF4_55_SMB       0x0368
   40 #define NFSMB_DEVICEID_NF4_61_SMB       0x03eb
   41 
   42 /* PCI Configuration space registers */
   43 #define NF2PCI_SMBASE_1         PCIR_BAR(4)
   44 #define NF2PCI_SMBASE_2         PCIR_BAR(5)
   45 
   46 /*
   47  * ACPI 3.0, Chapter 12, SMBus Host Controller Interface.
   48  */
   49 #define SMB_PRTCL               0x00    /* protocol */
   50 #define SMB_STS                 0x01    /* status */
   51 #define SMB_ADDR                0x02    /* address */
   52 #define SMB_CMD                 0x03    /* command */
   53 #define SMB_DATA                0x04    /* 32 data registers */
   54 #define SMB_BCNT                0x24    /* number of data bytes */
   55 #define SMB_ALRM_A              0x25    /* alarm address */
   56 #define SMB_ALRM_D              0x26    /* 2 bytes alarm data */
   57 
   58 #define SMB_STS_DONE            0x80
   59 #define SMB_STS_ALRM            0x40
   60 #define SMB_STS_RES             0x20
   61 #define SMB_STS_STATUS          0x1f
   62 #define SMB_STS_OK              0x00    /* OK */
   63 #define SMB_STS_UF              0x07    /* Unknown Failure */
   64 #define SMB_STS_DANA            0x10    /* Device Address Not Acknowledged */
   65 #define SMB_STS_DED             0x11    /* Device Error Detected */
   66 #define SMB_STS_DCAD            0x12    /* Device Command Access Denied */
   67 #define SMB_STS_UE              0x13    /* Unknown Error */
   68 #define SMB_STS_DAD             0x17    /* Device Access Denied */
   69 #define SMB_STS_T               0x18    /* Timeout */
   70 #define SMB_STS_HUP             0x19    /* Host Unsupported Protocol */
   71 #define SMB_STS_B               0x1A    /* Busy */
   72 #define SMB_STS_PEC             0x1F    /* PEC (CRC-8) Error */
   73 
   74 #define SMB_PRTCL_WRITE         0x00
   75 #define SMB_PRTCL_READ          0x01
   76 #define SMB_PRTCL_QUICK         0x02
   77 #define SMB_PRTCL_BYTE          0x04
   78 #define SMB_PRTCL_BYTE_DATA     0x06
   79 #define SMB_PRTCL_WORD_DATA     0x08
   80 #define SMB_PRTCL_BLOCK_DATA    0x0a
   81 #define SMB_PRTCL_PROC_CALL     0x0c
   82 #define SMB_PRTCL_BLOCK_PROC_CALL 0x0d
   83 #define SMB_PRTCL_PEC           0x80
   84 
   85 struct nfsmb_softc {
   86         int rid;
   87         struct resource *res;
   88         bus_space_tag_t smbst;
   89         bus_space_handle_t smbsh;
   90         device_t smbus;
   91         device_t subdev;
   92         struct mtx lock;
   93 };
   94 
   95 #define NFSMB_LOCK(nfsmb)               mtx_lock(&(nfsmb)->lock)
   96 #define NFSMB_UNLOCK(nfsmb)             mtx_unlock(&(nfsmb)->lock)
   97 #define NFSMB_LOCK_ASSERT(nfsmb)        mtx_assert(&(nfsmb)->lock, MA_OWNED)
   98 
   99 #define NFSMB_SMBINB(nfsmb, register)                                   \
  100         (bus_space_read_1(nfsmb->smbst, nfsmb->smbsh, register))
  101 #define NFSMB_SMBOUTB(nfsmb, register, value) \
  102         (bus_space_write_1(nfsmb->smbst, nfsmb->smbsh, register, value))
  103 
  104 static int      nfsmb_detach(device_t dev);
  105 static int      nfsmbsub_detach(device_t dev);
  106 
  107 static int
  108 nfsmbsub_probe(device_t dev)
  109 {
  110 
  111         device_set_desc(dev, "nForce2/3/4 MCP SMBus Controller");
  112         return (BUS_PROBE_DEFAULT);
  113 }
  114 
  115 static int
  116 nfsmb_probe(device_t dev)
  117 {
  118         u_int16_t vid;
  119         u_int16_t did;
  120 
  121         vid = pci_get_vendor(dev);
  122         did = pci_get_device(dev);
  123 
  124         if (vid == NFSMB_VENDORID_NVIDIA) {
  125                 switch(did) {
  126                 case NFSMB_DEVICEID_NF2_SMB:
  127                 case NFSMB_DEVICEID_NF2_ULTRA_SMB:
  128                 case NFSMB_DEVICEID_NF3_PRO150_SMB:
  129                 case NFSMB_DEVICEID_NF3_250GB_SMB:
  130                 case NFSMB_DEVICEID_NF4_SMB:
  131                 case NFSMB_DEVICEID_NF4_04_SMB:
  132                 case NFSMB_DEVICEID_NF4_51_SMB:
  133                 case NFSMB_DEVICEID_NF4_55_SMB:
  134                 case NFSMB_DEVICEID_NF4_61_SMB:
  135                         device_set_desc(dev, "nForce2/3/4 MCP SMBus Controller");
  136                         return (BUS_PROBE_DEFAULT);
  137                 }
  138         }
  139 
  140         return (ENXIO);
  141 }
  142 
  143 static int
  144 nfsmbsub_attach(device_t dev)
  145 {
  146         device_t parent;
  147         struct nfsmb_softc *nfsmbsub_sc = device_get_softc(dev);
  148 
  149         parent = device_get_parent(dev);
  150 
  151         nfsmbsub_sc->rid = NF2PCI_SMBASE_2;
  152 
  153         nfsmbsub_sc->res = bus_alloc_resource_any(parent, SYS_RES_IOPORT,
  154             &nfsmbsub_sc->rid, RF_ACTIVE);
  155         if (nfsmbsub_sc->res == NULL) {
  156                 /* Older incarnations of the device used non-standard BARs. */
  157                 nfsmbsub_sc->rid = 0x54;
  158                 nfsmbsub_sc->res = bus_alloc_resource_any(parent,
  159                     SYS_RES_IOPORT, &nfsmbsub_sc->rid, RF_ACTIVE);
  160                 if (nfsmbsub_sc->res == NULL) {
  161                         device_printf(dev, "could not map i/o space\n");
  162                         return (ENXIO);
  163                 }
  164         }
  165         nfsmbsub_sc->smbst = rman_get_bustag(nfsmbsub_sc->res);
  166         nfsmbsub_sc->smbsh = rman_get_bushandle(nfsmbsub_sc->res);
  167         mtx_init(&nfsmbsub_sc->lock, device_get_nameunit(dev), "nfsmb",
  168             MTX_DEF);
  169 
  170         nfsmbsub_sc->smbus = device_add_child(dev, "smbus", -1);
  171         if (nfsmbsub_sc->smbus == NULL) {
  172                 nfsmbsub_detach(dev);
  173                 return (EINVAL);
  174         }
  175 
  176         bus_generic_attach(dev);
  177 
  178         return (0);
  179 }
  180 
  181 static int
  182 nfsmb_attach(device_t dev)
  183 {
  184         struct nfsmb_softc *nfsmb_sc = device_get_softc(dev);
  185 
  186         /* Allocate I/O space */
  187         nfsmb_sc->rid = NF2PCI_SMBASE_1;
  188 
  189         nfsmb_sc->res = bus_alloc_resource_any(dev, SYS_RES_IOPORT,
  190                 &nfsmb_sc->rid, RF_ACTIVE);
  191 
  192         if (nfsmb_sc->res == NULL) {
  193                 /* Older incarnations of the device used non-standard BARs. */
  194                 nfsmb_sc->rid = 0x50;
  195                 nfsmb_sc->res = bus_alloc_resource_any(dev,
  196                     SYS_RES_IOPORT, &nfsmb_sc->rid, RF_ACTIVE);
  197                 if (nfsmb_sc->res == NULL) {
  198                         device_printf(dev, "could not map i/o space\n");
  199                         return (ENXIO);
  200                 }
  201         }
  202 
  203         nfsmb_sc->smbst = rman_get_bustag(nfsmb_sc->res);
  204         nfsmb_sc->smbsh = rman_get_bushandle(nfsmb_sc->res);
  205         mtx_init(&nfsmb_sc->lock, device_get_nameunit(dev), "nfsmb", MTX_DEF);
  206 
  207         /* Allocate a new smbus device */
  208         nfsmb_sc->smbus = device_add_child(dev, "smbus", -1);
  209         if (!nfsmb_sc->smbus) {
  210                 nfsmb_detach(dev);
  211                 return (EINVAL);
  212         }
  213 
  214         nfsmb_sc->subdev = NULL;
  215         switch (pci_get_device(dev)) {
  216         case NFSMB_DEVICEID_NF2_SMB:
  217         case NFSMB_DEVICEID_NF2_ULTRA_SMB:
  218         case NFSMB_DEVICEID_NF3_PRO150_SMB:
  219         case NFSMB_DEVICEID_NF3_250GB_SMB:
  220         case NFSMB_DEVICEID_NF4_SMB:
  221         case NFSMB_DEVICEID_NF4_04_SMB:
  222         case NFSMB_DEVICEID_NF4_51_SMB:
  223         case NFSMB_DEVICEID_NF4_55_SMB:
  224         case NFSMB_DEVICEID_NF4_61_SMB:
  225                 /* Trying to add secondary device as slave */
  226                 nfsmb_sc->subdev = device_add_child(dev, "nfsmb", -1);
  227                 if (!nfsmb_sc->subdev) {
  228                         nfsmb_detach(dev);
  229                         return (EINVAL);
  230                 }
  231                 break;
  232         default:
  233                 break;
  234         }
  235 
  236         bus_generic_attach(dev);
  237 
  238         return (0);
  239 }
  240 
  241 static int
  242 nfsmbsub_detach(device_t dev)
  243 {
  244         device_t parent;
  245         struct nfsmb_softc *nfsmbsub_sc = device_get_softc(dev);
  246 
  247         parent = device_get_parent(dev);
  248 
  249         if (nfsmbsub_sc->smbus) {
  250                 device_delete_child(dev, nfsmbsub_sc->smbus);
  251                 nfsmbsub_sc->smbus = NULL;
  252         }
  253         mtx_destroy(&nfsmbsub_sc->lock);
  254         if (nfsmbsub_sc->res) {
  255                 bus_release_resource(parent, SYS_RES_IOPORT, nfsmbsub_sc->rid,
  256                     nfsmbsub_sc->res);
  257                 nfsmbsub_sc->res = NULL;
  258         }
  259         return (0);
  260 }
  261 
  262 static int
  263 nfsmb_detach(device_t dev)
  264 {
  265         struct nfsmb_softc *nfsmb_sc = device_get_softc(dev);
  266 
  267         if (nfsmb_sc->subdev) {
  268                 device_delete_child(dev, nfsmb_sc->subdev);
  269                 nfsmb_sc->subdev = NULL;
  270         }
  271 
  272         if (nfsmb_sc->smbus) {
  273                 device_delete_child(dev, nfsmb_sc->smbus);
  274                 nfsmb_sc->smbus = NULL;
  275         }
  276 
  277         mtx_destroy(&nfsmb_sc->lock);
  278         if (nfsmb_sc->res) {
  279                 bus_release_resource(dev, SYS_RES_IOPORT, nfsmb_sc->rid,
  280                     nfsmb_sc->res);
  281                 nfsmb_sc->res = NULL;
  282         }
  283 
  284         return (0);
  285 }
  286 
  287 static int
  288 nfsmb_callback(device_t dev, int index, void *data)
  289 {
  290         int error = 0;
  291 
  292         switch (index) {
  293         case SMB_REQUEST_BUS:
  294         case SMB_RELEASE_BUS:
  295                 break;
  296         default:
  297                 error = EINVAL;
  298         }
  299 
  300         return (error);
  301 }
  302 
  303 static int
  304 nfsmb_wait(struct nfsmb_softc *sc)
  305 {
  306         u_char sts;
  307         int error, count;
  308 
  309         NFSMB_LOCK_ASSERT(sc);
  310         if (NFSMB_SMBINB(sc, SMB_PRTCL) != 0)
  311         {
  312                 count = 10000;
  313                 do {
  314                         DELAY(500);
  315                 } while (NFSMB_SMBINB(sc, SMB_PRTCL) != 0 && count--);
  316                 if (count == 0)
  317                         return (SMB_ETIMEOUT);
  318         }
  319 
  320         sts = NFSMB_SMBINB(sc, SMB_STS) & SMB_STS_STATUS;
  321         NFSMB_DEBUG(printf("nfsmb: STS=0x%x\n", sts));
  322 
  323         switch (sts) {
  324         case SMB_STS_OK:
  325                 error = SMB_ENOERR;
  326                 break;
  327         case SMB_STS_DANA:
  328                 error = SMB_ENOACK;
  329                 break;
  330         case SMB_STS_B:
  331                 error = SMB_EBUSY;
  332                 break;
  333         case SMB_STS_T:
  334                 error = SMB_ETIMEOUT;
  335                 break;
  336         case SMB_STS_DCAD:
  337         case SMB_STS_DAD:
  338         case SMB_STS_HUP:
  339                 error = SMB_ENOTSUPP;
  340                 break;
  341         default:
  342                 error = SMB_EBUSERR;
  343                 break;
  344         }
  345 
  346         return (error);
  347 }
  348 
  349 static int
  350 nfsmb_quick(device_t dev, u_char slave, int how)
  351 {
  352         struct nfsmb_softc *sc = (struct nfsmb_softc *)device_get_softc(dev);
  353         u_char protocol;
  354         int error;
  355 
  356         protocol = SMB_PRTCL_QUICK;
  357 
  358         switch (how) {
  359         case SMB_QWRITE:
  360                 protocol |= SMB_PRTCL_WRITE;
  361                 NFSMB_DEBUG(printf("nfsmb: QWRITE to 0x%x", slave));
  362                 break;
  363         case SMB_QREAD:
  364                 protocol |= SMB_PRTCL_READ;
  365                 NFSMB_DEBUG(printf("nfsmb: QREAD to 0x%x", slave));
  366                 break;
  367         default:
  368                 panic("%s: unknown QUICK command (%x)!", __func__, how);
  369         }
  370 
  371         NFSMB_LOCK(sc);
  372         NFSMB_SMBOUTB(sc, SMB_ADDR, slave);
  373         NFSMB_SMBOUTB(sc, SMB_PRTCL, protocol);
  374 
  375         error = nfsmb_wait(sc);
  376 
  377         NFSMB_DEBUG(printf(", error=0x%x\n", error));
  378         NFSMB_UNLOCK(sc);
  379 
  380         return (error);
  381 }
  382 
  383 static int
  384 nfsmb_sendb(device_t dev, u_char slave, char byte)
  385 {
  386         struct nfsmb_softc *sc = (struct nfsmb_softc *)device_get_softc(dev);
  387         int error;
  388 
  389         NFSMB_LOCK(sc);
  390         NFSMB_SMBOUTB(sc, SMB_CMD, byte);
  391         NFSMB_SMBOUTB(sc, SMB_ADDR, slave);
  392         NFSMB_SMBOUTB(sc, SMB_PRTCL, SMB_PRTCL_WRITE | SMB_PRTCL_BYTE);
  393 
  394         error = nfsmb_wait(sc);
  395 
  396         NFSMB_DEBUG(printf("nfsmb: SENDB to 0x%x, byte=0x%x, error=0x%x\n", slave, byte, error));
  397         NFSMB_UNLOCK(sc);
  398 
  399         return (error);
  400 }
  401 
  402 static int
  403 nfsmb_recvb(device_t dev, u_char slave, char *byte)
  404 {
  405         struct nfsmb_softc *sc = (struct nfsmb_softc *)device_get_softc(dev);
  406         int error;
  407 
  408         NFSMB_LOCK(sc);
  409         NFSMB_SMBOUTB(sc, SMB_ADDR, slave);
  410         NFSMB_SMBOUTB(sc, SMB_PRTCL, SMB_PRTCL_READ | SMB_PRTCL_BYTE);
  411 
  412         if ((error = nfsmb_wait(sc)) == SMB_ENOERR)
  413                 *byte = NFSMB_SMBINB(sc, SMB_DATA);
  414 
  415         NFSMB_DEBUG(printf("nfsmb: RECVB from 0x%x, byte=0x%x, error=0x%x\n", slave, *byte, error));
  416         NFSMB_UNLOCK(sc);
  417 
  418         return (error);
  419 }
  420 
  421 static int
  422 nfsmb_writeb(device_t dev, u_char slave, char cmd, char byte)
  423 {
  424         struct nfsmb_softc *sc = (struct nfsmb_softc *)device_get_softc(dev);
  425         int error;
  426 
  427         NFSMB_LOCK(sc);
  428         NFSMB_SMBOUTB(sc, SMB_CMD, cmd);
  429         NFSMB_SMBOUTB(sc, SMB_DATA, byte);
  430         NFSMB_SMBOUTB(sc, SMB_ADDR, slave);
  431         NFSMB_SMBOUTB(sc, SMB_PRTCL, SMB_PRTCL_WRITE | SMB_PRTCL_BYTE_DATA);
  432 
  433         error = nfsmb_wait(sc);
  434 
  435         NFSMB_DEBUG(printf("nfsmb: WRITEB to 0x%x, cmd=0x%x, byte=0x%x, error=0x%x\n", slave, cmd, byte, error));
  436         NFSMB_UNLOCK(sc);
  437 
  438         return (error);
  439 }
  440 
  441 static int
  442 nfsmb_readb(device_t dev, u_char slave, char cmd, char *byte)
  443 {
  444         struct nfsmb_softc *sc = (struct nfsmb_softc *)device_get_softc(dev);
  445         int error;
  446 
  447         NFSMB_LOCK(sc);
  448         NFSMB_SMBOUTB(sc, SMB_CMD, cmd);
  449         NFSMB_SMBOUTB(sc, SMB_ADDR, slave);
  450         NFSMB_SMBOUTB(sc, SMB_PRTCL, SMB_PRTCL_READ | SMB_PRTCL_BYTE_DATA);
  451 
  452         if ((error = nfsmb_wait(sc)) == SMB_ENOERR)
  453                 *byte = NFSMB_SMBINB(sc, SMB_DATA);
  454 
  455         NFSMB_DEBUG(printf("nfsmb: READB from 0x%x, cmd=0x%x, byte=0x%x, error=0x%x\n", slave, cmd, (unsigned char)*byte, error));
  456         NFSMB_UNLOCK(sc);
  457 
  458         return (error);
  459 }
  460 
  461 static int
  462 nfsmb_writew(device_t dev, u_char slave, char cmd, short word)
  463 {
  464         struct nfsmb_softc *sc = (struct nfsmb_softc *)device_get_softc(dev);
  465         int error;
  466 
  467         NFSMB_LOCK(sc);
  468         NFSMB_SMBOUTB(sc, SMB_CMD, cmd);
  469         NFSMB_SMBOUTB(sc, SMB_DATA, word);
  470         NFSMB_SMBOUTB(sc, SMB_DATA + 1, word >> 8);
  471         NFSMB_SMBOUTB(sc, SMB_ADDR, slave);
  472         NFSMB_SMBOUTB(sc, SMB_PRTCL, SMB_PRTCL_WRITE | SMB_PRTCL_WORD_DATA);
  473 
  474         error = nfsmb_wait(sc);
  475 
  476         NFSMB_DEBUG(printf("nfsmb: WRITEW to 0x%x, cmd=0x%x, word=0x%x, error=0x%x\n", slave, cmd, word, error));
  477         NFSMB_UNLOCK(sc);
  478 
  479         return (error);
  480 }
  481 
  482 static int
  483 nfsmb_readw(device_t dev, u_char slave, char cmd, short *word)
  484 {
  485         struct nfsmb_softc *sc = (struct nfsmb_softc *)device_get_softc(dev);
  486         int error;
  487 
  488         NFSMB_LOCK(sc);
  489         NFSMB_SMBOUTB(sc, SMB_CMD, cmd);
  490         NFSMB_SMBOUTB(sc, SMB_ADDR, slave);
  491         NFSMB_SMBOUTB(sc, SMB_PRTCL, SMB_PRTCL_READ | SMB_PRTCL_WORD_DATA);
  492 
  493         if ((error = nfsmb_wait(sc)) == SMB_ENOERR)
  494                 *word = NFSMB_SMBINB(sc, SMB_DATA) |
  495                     (NFSMB_SMBINB(sc, SMB_DATA + 1) << 8);
  496 
  497         NFSMB_DEBUG(printf("nfsmb: READW from 0x%x, cmd=0x%x, word=0x%x, error=0x%x\n", slave, cmd, (unsigned short)*word, error));
  498         NFSMB_UNLOCK(sc);
  499 
  500         return (error);
  501 }
  502 
  503 static int
  504 nfsmb_bwrite(device_t dev, u_char slave, char cmd, u_char count, char *buf)
  505 {
  506         struct nfsmb_softc *sc = (struct nfsmb_softc *)device_get_softc(dev);
  507         u_char i;
  508         int error;
  509 
  510         if (count < 1 || count > 32)
  511                 return (SMB_EINVAL);
  512 
  513         NFSMB_LOCK(sc);
  514         NFSMB_SMBOUTB(sc, SMB_CMD, cmd);
  515         NFSMB_SMBOUTB(sc, SMB_BCNT, count);
  516         for (i = 0; i < count; i++)
  517                 NFSMB_SMBOUTB(sc, SMB_DATA + i, buf[i]);
  518         NFSMB_SMBOUTB(sc, SMB_ADDR, slave);
  519         NFSMB_SMBOUTB(sc, SMB_PRTCL, SMB_PRTCL_WRITE | SMB_PRTCL_BLOCK_DATA);
  520 
  521         error = nfsmb_wait(sc);
  522 
  523         NFSMB_DEBUG(printf("nfsmb: WRITEBLK to 0x%x, count=0x%x, cmd=0x%x, error=0x%x", slave, count, cmd, error));
  524         NFSMB_UNLOCK(sc);
  525 
  526         return (error);
  527 }
  528 
  529 static int
  530 nfsmb_bread(device_t dev, u_char slave, char cmd, u_char *count, char *buf)
  531 {
  532         struct nfsmb_softc *sc = (struct nfsmb_softc *)device_get_softc(dev);
  533         u_char data, len, i;
  534         int error;
  535 
  536         if (*count < 1 || *count > 32)
  537                 return (SMB_EINVAL);
  538 
  539         NFSMB_LOCK(sc);
  540         NFSMB_SMBOUTB(sc, SMB_CMD, cmd);
  541         NFSMB_SMBOUTB(sc, SMB_ADDR, slave);
  542         NFSMB_SMBOUTB(sc, SMB_PRTCL, SMB_PRTCL_READ | SMB_PRTCL_BLOCK_DATA);
  543 
  544         if ((error = nfsmb_wait(sc)) == SMB_ENOERR) {
  545                 len = NFSMB_SMBINB(sc, SMB_BCNT);
  546                 for (i = 0; i < len; i++) {
  547                         data = NFSMB_SMBINB(sc, SMB_DATA + i);
  548                         if (i < *count)
  549                                 buf[i] = data;
  550                 }
  551                 *count = len;
  552         }
  553 
  554         NFSMB_DEBUG(printf("nfsmb: READBLK to 0x%x, count=0x%x, cmd=0x%x, error=0x%x", slave, *count, cmd, error));
  555         NFSMB_UNLOCK(sc);
  556 
  557         return (error);
  558 }
  559 
  560 static device_method_t nfsmb_methods[] = {
  561         /* Device interface */
  562         DEVMETHOD(device_probe,         nfsmb_probe),
  563         DEVMETHOD(device_attach,        nfsmb_attach),
  564         DEVMETHOD(device_detach,        nfsmb_detach),
  565 
  566         /* SMBus interface */
  567         DEVMETHOD(smbus_callback,       nfsmb_callback),
  568         DEVMETHOD(smbus_quick,          nfsmb_quick),
  569         DEVMETHOD(smbus_sendb,          nfsmb_sendb),
  570         DEVMETHOD(smbus_recvb,          nfsmb_recvb),
  571         DEVMETHOD(smbus_writeb,         nfsmb_writeb),
  572         DEVMETHOD(smbus_readb,          nfsmb_readb),
  573         DEVMETHOD(smbus_writew,         nfsmb_writew),
  574         DEVMETHOD(smbus_readw,          nfsmb_readw),
  575         DEVMETHOD(smbus_bwrite,         nfsmb_bwrite),
  576         DEVMETHOD(smbus_bread,          nfsmb_bread),
  577 
  578         { 0, 0 }
  579 };
  580 
  581 static device_method_t nfsmbsub_methods[] = {
  582         /* Device interface */
  583         DEVMETHOD(device_probe,         nfsmbsub_probe),
  584         DEVMETHOD(device_attach,        nfsmbsub_attach),
  585         DEVMETHOD(device_detach,        nfsmbsub_detach),
  586 
  587         /* SMBus interface */
  588         DEVMETHOD(smbus_callback,       nfsmb_callback),
  589         DEVMETHOD(smbus_quick,          nfsmb_quick),
  590         DEVMETHOD(smbus_sendb,          nfsmb_sendb),
  591         DEVMETHOD(smbus_recvb,          nfsmb_recvb),
  592         DEVMETHOD(smbus_writeb,         nfsmb_writeb),
  593         DEVMETHOD(smbus_readb,          nfsmb_readb),
  594         DEVMETHOD(smbus_writew,         nfsmb_writew),
  595         DEVMETHOD(smbus_readw,          nfsmb_readw),
  596         DEVMETHOD(smbus_bwrite,         nfsmb_bwrite),
  597         DEVMETHOD(smbus_bread,          nfsmb_bread),
  598 
  599         { 0, 0 }
  600 };
  601 
  602 static devclass_t nfsmb_devclass;
  603 
  604 static driver_t nfsmb_driver = {
  605         "nfsmb",
  606         nfsmb_methods,
  607         sizeof(struct nfsmb_softc),
  608 };
  609 
  610 static driver_t nfsmbsub_driver = {
  611         "nfsmb",
  612         nfsmbsub_methods,
  613         sizeof(struct nfsmb_softc),
  614 };
  615 
  616 DRIVER_MODULE(nfsmb, pci, nfsmb_driver, nfsmb_devclass, 0, 0);
  617 DRIVER_MODULE(nfsmb, nfsmb, nfsmbsub_driver, nfsmb_devclass, 0, 0);
  618 DRIVER_MODULE(smbus, nfsmb, smbus_driver, smbus_devclass, 0, 0);
  619 
  620 MODULE_DEPEND(nfsmb, pci, 1, 1, 1);
  621 MODULE_DEPEND(nfsmb, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER);
  622 MODULE_VERSION(nfsmb, 1);

Cache object: 069c7956b7f833c36ed96ec83fcbfe17


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.