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