29 30#include <sys/param.h> 31#include <sys/module.h> 32#include <sys/systm.h> 33#include <sys/kernel.h> 34#include <sys/bus.h> 35#include <sys/endian.h> 36#include <sys/malloc.h> 37#include <sys/lock.h> 38#include <sys/mutex.h> 39#include <vm/uma.h> 40#include <machine/stdarg.h> 41#include <machine/resource.h> 42#include <machine/bus.h> 43#include <sys/rman.h> 44#include <dev/pci/pcivar.h> 45#include <dev/pci/pcireg.h> 46#include "mvs.h" 47 48/* local prototypes */ 49static int mvs_setup_interrupt(device_t dev); 50static void mvs_intr(void *data); 51static int mvs_suspend(device_t dev); 52static int mvs_resume(device_t dev); 53static int mvs_ctlr_setup(device_t dev); 54 55static struct { 56 uint32_t id; 57 uint8_t rev; 58 const char *name; 59 int ports; 60 int quirks; 61} mvs_ids[] = { 62 {0x504011ab, 0x00, "Marvell 88SX5040", 4, MVS_Q_GENI}, 63 {0x504111ab, 0x00, "Marvell 88SX5041", 4, MVS_Q_GENI}, 64 {0x508011ab, 0x00, "Marvell 88SX5080", 8, MVS_Q_GENI}, 65 {0x508111ab, 0x00, "Marvell 88SX5081", 8, MVS_Q_GENI}, 66 {0x604011ab, 0x00, "Marvell 88SX6040", 4, MVS_Q_GENII}, 67 {0x604111ab, 0x00, "Marvell 88SX6041", 4, MVS_Q_GENII}, 68 {0x604211ab, 0x00, "Marvell 88SX6042", 4, MVS_Q_GENIIE}, 69 {0x608011ab, 0x00, "Marvell 88SX6080", 8, MVS_Q_GENII}, 70 {0x608111ab, 0x00, "Marvell 88SX6081", 8, MVS_Q_GENII}, 71 {0x704211ab, 0x00, "Marvell 88SX7042", 4, MVS_Q_GENIIE|MVS_Q_CT}, 72 {0x02419005, 0x00, "Adaptec 1420SA", 4, MVS_Q_GENII}, 73 {0x02439005, 0x00, "Adaptec 1430SA", 4, MVS_Q_GENIIE|MVS_Q_CT}, 74 {0x00000000, 0x00, NULL, 0, 0} 75}; 76 77static int 78mvs_probe(device_t dev) 79{ 80 char buf[64]; 81 int i; 82 uint32_t devid = pci_get_devid(dev); 83 uint8_t revid = pci_get_revid(dev); 84 85 for (i = 0; mvs_ids[i].id != 0; i++) { 86 if (mvs_ids[i].id == devid && 87 mvs_ids[i].rev <= revid) { 88 snprintf(buf, sizeof(buf), "%s SATA controller", 89 mvs_ids[i].name); 90 device_set_desc_copy(dev, buf); 91 return (BUS_PROBE_VENDOR); 92 } 93 } 94 return (ENXIO); 95} 96 97static int 98mvs_attach(device_t dev) 99{ 100 struct mvs_controller *ctlr = device_get_softc(dev); 101 device_t child; 102 int error, unit, i; 103 uint32_t devid = pci_get_devid(dev); 104 uint8_t revid = pci_get_revid(dev); 105 106 ctlr->dev = dev; 107 i = 0; 108 while (mvs_ids[i].id != 0 && 109 (mvs_ids[i].id != devid || 110 mvs_ids[i].rev > revid)) 111 i++; 112 ctlr->channels = mvs_ids[i].ports; 113 ctlr->quirks = mvs_ids[i].quirks; 114 resource_int_value(device_get_name(dev), 115 device_get_unit(dev), "ccc", &ctlr->ccc); 116 ctlr->cccc = 8; 117 resource_int_value(device_get_name(dev), 118 device_get_unit(dev), "cccc", &ctlr->cccc); 119 if (ctlr->ccc == 0 || ctlr->cccc == 0) { 120 ctlr->ccc = 0; 121 ctlr->cccc = 0; 122 } 123 if (ctlr->ccc > 100000) 124 ctlr->ccc = 100000; 125 device_printf(dev, 126 "Gen-%s, %d %sGbps ports, Port Multiplier %s%s\n", 127 ((ctlr->quirks & MVS_Q_GENI) ? "I" : 128 ((ctlr->quirks & MVS_Q_GENII) ? "II" : "IIe")), 129 ctlr->channels, 130 ((ctlr->quirks & MVS_Q_GENI) ? "1.5" : "3"), 131 ((ctlr->quirks & MVS_Q_GENI) ? 132 "not supported" : "supported"), 133 ((ctlr->quirks & MVS_Q_GENIIE) ? 134 " with FBS" : "")); 135 mtx_init(&ctlr->mtx, "MVS controller lock", NULL, MTX_DEF); 136 /* We should have a memory BAR(0). */ 137 ctlr->r_rid = PCIR_BAR(0); 138 if (!(ctlr->r_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 139 &ctlr->r_rid, RF_ACTIVE))) 140 return ENXIO; 141 /* Setup our own memory management for channels. */
|
144 ctlr->sc_iomem.rm_type = RMAN_ARRAY; 145 ctlr->sc_iomem.rm_descr = "I/O memory addresses"; 146 if ((error = rman_init(&ctlr->sc_iomem)) != 0) { 147 bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem); 148 return (error); 149 } 150 if ((error = rman_manage_region(&ctlr->sc_iomem, 151 rman_get_start(ctlr->r_mem), rman_get_end(ctlr->r_mem))) != 0) { 152 bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem); 153 rman_fini(&ctlr->sc_iomem); 154 return (error); 155 } 156 pci_enable_busmaster(dev); 157 mvs_ctlr_setup(dev); 158 /* Setup interrupts. */ 159 if (mvs_setup_interrupt(dev)) { 160 bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem); 161 rman_fini(&ctlr->sc_iomem); 162 return ENXIO; 163 } 164 /* Attach all channels on this controller */ 165 for (unit = 0; unit < ctlr->channels; unit++) { 166 child = device_add_child(dev, "mvsch", -1); 167 if (child == NULL) 168 device_printf(dev, "failed to add channel device\n"); 169 else 170 device_set_ivars(child, (void *)(intptr_t)unit); 171 } 172 bus_generic_attach(dev); 173 return 0; 174} 175 176static int 177mvs_detach(device_t dev) 178{ 179 struct mvs_controller *ctlr = device_get_softc(dev); 180 device_t *children; 181 int nchildren, i; 182 183 /* Detach & delete all children */ 184 if (!device_get_children(dev, &children, &nchildren)) { 185 for (i = 0; i < nchildren; i++) 186 device_delete_child(dev, children[i]); 187 free(children, M_TEMP); 188 } 189 /* Free interrupt. */ 190 if (ctlr->irq.r_irq) { 191 bus_teardown_intr(dev, ctlr->irq.r_irq, 192 ctlr->irq.handle); 193 bus_release_resource(dev, SYS_RES_IRQ, 194 ctlr->irq.r_irq_rid, ctlr->irq.r_irq); 195 } 196 pci_release_msi(dev); 197 /* Free memory. */ 198 rman_fini(&ctlr->sc_iomem); 199 if (ctlr->r_mem) 200 bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem); 201 mtx_destroy(&ctlr->mtx); 202 return (0); 203} 204 205static int 206mvs_ctlr_setup(device_t dev) 207{ 208 struct mvs_controller *ctlr = device_get_softc(dev); 209 int i, ccc = ctlr->ccc, cccc = ctlr->cccc, ccim = 0; 210 211 /* Mask chip interrupts */ 212 ATA_OUTL(ctlr->r_mem, CHIP_MIM, 0x00000000); 213 /* Mask PCI interrupts */ 214 ATA_OUTL(ctlr->r_mem, CHIP_PCIIM, 0x00000000); 215 /* Clear PCI interrupts */ 216 ATA_OUTL(ctlr->r_mem, CHIP_PCIIC, 0x00000000); 217 if (ccc && bootverbose) { 218 device_printf(dev, 219 "CCC with %dus/%dcmd enabled\n", 220 ctlr->ccc, ctlr->cccc); 221 } 222 ccc *= 150; 223 /* Configure chip-global CCC */ 224 if (ctlr->channels > 4 && (ctlr->quirks & MVS_Q_GENI) == 0) { 225 ATA_OUTL(ctlr->r_mem, CHIP_ICT, cccc); 226 ATA_OUTL(ctlr->r_mem, CHIP_ITT, ccc); 227 ATA_OUTL(ctlr->r_mem, CHIP_ICC, ~CHIP_ICC_ALL_PORTS); 228 if (ccc) 229 ccim |= IC_ALL_PORTS_COAL_DONE; 230 ccc = 0; 231 cccc = 0; 232 } 233 for (i = 0; i < ctlr->channels / 4; i++) { 234 /* Configure per-HC CCC */ 235 ATA_OUTL(ctlr->r_mem, HC_BASE(i) + HC_ICT, cccc); 236 ATA_OUTL(ctlr->r_mem, HC_BASE(i) + HC_ITT, ccc); 237 if (ccc) 238 ccim |= (IC_HC0_COAL_DONE << (i * IC_HC_SHIFT)); 239 /* Clear HC interrupts */ 240 ATA_OUTL(ctlr->r_mem, HC_BASE(i) + HC_IC, 0x00000000); 241 } 242 /* Enable chip interrupts */ 243 ctlr->gmim = (ccim ? ccim : (IC_DONE_HC0 | IC_DONE_HC1)) | 244 IC_ERR_HC0 | IC_ERR_HC1; 245 ctlr->mim = ctlr->gmim | ctlr->pmim; 246 ATA_OUTL(ctlr->r_mem, CHIP_MIM, ctlr->mim); 247 /* Enable PCI interrupts */ 248 ATA_OUTL(ctlr->r_mem, CHIP_PCIIM, 0x007fffff); 249 return (0); 250} 251 252static void 253mvs_edma(device_t dev, device_t child, int mode) 254{ 255 struct mvs_controller *ctlr = device_get_softc(dev); 256 int unit = ((struct mvs_channel *)device_get_softc(child))->unit; 257 int bit = IC_DONE_IRQ << (unit * 2 + unit / 4) ; 258 259 if (ctlr->ccc == 0) 260 return; 261 /* CCC is not working for non-EDMA mode. Unmask device interrupts. */ 262 mtx_lock(&ctlr->mtx); 263 if (mode == MVS_EDMA_OFF) 264 ctlr->pmim |= bit; 265 else 266 ctlr->pmim &= ~bit; 267 ctlr->mim = ctlr->gmim | ctlr->pmim; 268 if (!ctlr->msia) 269 ATA_OUTL(ctlr->r_mem, CHIP_MIM, ctlr->mim); 270 mtx_unlock(&ctlr->mtx); 271} 272 273static int 274mvs_suspend(device_t dev) 275{ 276 struct mvs_controller *ctlr = device_get_softc(dev); 277 278 bus_generic_suspend(dev); 279 /* Mask chip interrupts */ 280 ATA_OUTL(ctlr->r_mem, CHIP_MIM, 0x00000000); 281 /* Mask PCI interrupts */ 282 ATA_OUTL(ctlr->r_mem, CHIP_PCIIM, 0x00000000); 283 return 0; 284} 285 286static int 287mvs_resume(device_t dev) 288{ 289 290 mvs_ctlr_setup(dev); 291 return (bus_generic_resume(dev)); 292} 293 294static int 295mvs_setup_interrupt(device_t dev) 296{ 297 struct mvs_controller *ctlr = device_get_softc(dev); 298 int msi = 0; 299 300 /* Process hints. */ 301 resource_int_value(device_get_name(dev), 302 device_get_unit(dev), "msi", &msi); 303 if (msi < 0) 304 msi = 0; 305 else if (msi > 0) 306 msi = min(1, pci_msi_count(dev)); 307 /* Allocate MSI if needed/present. */ 308 if (msi && pci_alloc_msi(dev, &msi) != 0) 309 msi = 0; 310 ctlr->msi = msi; 311 /* Allocate all IRQs. */ 312 ctlr->irq.r_irq_rid = msi ? 1 : 0; 313 if (!(ctlr->irq.r_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, 314 &ctlr->irq.r_irq_rid, RF_SHAREABLE | RF_ACTIVE))) { 315 device_printf(dev, "unable to map interrupt\n"); 316 return (ENXIO); 317 } 318 if ((bus_setup_intr(dev, ctlr->irq.r_irq, ATA_INTR_FLAGS, NULL, 319 mvs_intr, ctlr, &ctlr->irq.handle))) { 320 device_printf(dev, "unable to setup interrupt\n"); 321 bus_release_resource(dev, SYS_RES_IRQ, 322 ctlr->irq.r_irq_rid, ctlr->irq.r_irq); 323 ctlr->irq.r_irq = 0; 324 return (ENXIO); 325 } 326 return (0); 327} 328 329/* 330 * Common case interrupt handler. 331 */ 332static void 333mvs_intr(void *data) 334{ 335 struct mvs_controller *ctlr = data; 336 struct mvs_intr_arg arg; 337 void (*function)(void *); 338 int p; 339 u_int32_t ic, aic; 340 341 ic = ATA_INL(ctlr->r_mem, CHIP_MIC); 342//device_printf(ctlr->dev, "irq MIC:%08x\n", ic); 343 if (ctlr->msi) { 344 /* We have to to mask MSI during processing. */ 345 mtx_lock(&ctlr->mtx); 346 ATA_OUTL(ctlr->r_mem, CHIP_MIM, 0); 347 ctlr->msia = 1; /* Deny MIM update during processing. */ 348 mtx_unlock(&ctlr->mtx); 349 } else if (ic == 0) 350 return; 351 /* Acknowledge all-ports CCC interrupt. */ 352 if (ic & IC_ALL_PORTS_COAL_DONE) 353 ATA_OUTL(ctlr->r_mem, CHIP_ICC, ~CHIP_ICC_ALL_PORTS); 354 for (p = 0; p < ctlr->channels; p++) { 355 if ((p & 3) == 0) { 356 if (p != 0) 357 ic >>= 1; 358 if ((ic & IC_HC0) == 0) { 359 p += 3; 360 ic >>= 8; 361 continue; 362 } 363 /* Acknowledge interrupts of this HC. */ 364 aic = 0; 365 if (ic & (IC_DONE_IRQ << 0)) 366 aic |= HC_IC_DONE(0) | HC_IC_DEV(0); 367 if (ic & (IC_DONE_IRQ << 2)) 368 aic |= HC_IC_DONE(1) | HC_IC_DEV(1); 369 if (ic & (IC_DONE_IRQ << 4)) 370 aic |= HC_IC_DONE(2) | HC_IC_DEV(2); 371 if (ic & (IC_DONE_IRQ << 6)) 372 aic |= HC_IC_DONE(3) | HC_IC_DEV(3); 373 if (ic & IC_HC0_COAL_DONE) 374 aic |= HC_IC_COAL; 375 ATA_OUTL(ctlr->r_mem, HC_BASE(p == 4) + HC_IC, ~aic); 376 } 377 /* Call per-port interrupt handler. */ 378 arg.cause = ic & (IC_ERR_IRQ|IC_DONE_IRQ); 379 if ((arg.cause != 0) && 380 (function = ctlr->interrupt[p].function)) { 381 arg.arg = ctlr->interrupt[p].argument; 382 function(&arg); 383 } 384 ic >>= 2; 385 } 386 if (ctlr->msi) { 387 /* Unmasking MSI triggers next interrupt, if needed. */ 388 mtx_lock(&ctlr->mtx); 389 ctlr->msia = 0; /* Allow MIM update. */ 390 ATA_OUTL(ctlr->r_mem, CHIP_MIM, ctlr->mim); 391 mtx_unlock(&ctlr->mtx); 392 } 393} 394 395static struct resource * 396mvs_alloc_resource(device_t dev, device_t child, int type, int *rid, 397 u_long start, u_long end, u_long count, u_int flags) 398{ 399 struct mvs_controller *ctlr = device_get_softc(dev); 400 int unit = ((struct mvs_channel *)device_get_softc(child))->unit; 401 struct resource *res = NULL; 402 int offset = HC_BASE(unit >> 2) + PORT_BASE(unit & 0x03); 403 long st; 404 405 switch (type) { 406 case SYS_RES_MEMORY: 407 st = rman_get_start(ctlr->r_mem); 408 res = rman_reserve_resource(&ctlr->sc_iomem, st + offset, 409 st + offset + PORT_SIZE - 1, PORT_SIZE, RF_ACTIVE, child); 410 if (res) { 411 bus_space_handle_t bsh; 412 bus_space_tag_t bst; 413 bsh = rman_get_bushandle(ctlr->r_mem); 414 bst = rman_get_bustag(ctlr->r_mem); 415 bus_space_subregion(bst, bsh, offset, PORT_SIZE, &bsh); 416 rman_set_bushandle(res, bsh); 417 rman_set_bustag(res, bst); 418 } 419 break; 420 case SYS_RES_IRQ: 421 if (*rid == ATA_IRQ_RID) 422 res = ctlr->irq.r_irq; 423 break; 424 } 425 return (res); 426} 427 428static int 429mvs_release_resource(device_t dev, device_t child, int type, int rid, 430 struct resource *r) 431{ 432 433 switch (type) { 434 case SYS_RES_MEMORY: 435 rman_release_resource(r); 436 return (0); 437 case SYS_RES_IRQ: 438 if (rid != ATA_IRQ_RID) 439 return ENOENT; 440 return (0); 441 } 442 return (EINVAL); 443} 444 445static int 446mvs_setup_intr(device_t dev, device_t child, struct resource *irq, 447 int flags, driver_filter_t *filter, driver_intr_t *function, 448 void *argument, void **cookiep) 449{ 450 struct mvs_controller *ctlr = device_get_softc(dev); 451 int unit = (intptr_t)device_get_ivars(child); 452 453 if (filter != NULL) { 454 printf("mvs.c: we cannot use a filter here\n"); 455 return (EINVAL); 456 } 457 ctlr->interrupt[unit].function = function; 458 ctlr->interrupt[unit].argument = argument; 459 return (0); 460} 461 462static int 463mvs_teardown_intr(device_t dev, device_t child, struct resource *irq, 464 void *cookie) 465{ 466 struct mvs_controller *ctlr = device_get_softc(dev); 467 int unit = (intptr_t)device_get_ivars(child); 468 469 ctlr->interrupt[unit].function = NULL; 470 ctlr->interrupt[unit].argument = NULL; 471 return (0); 472} 473 474static int 475mvs_print_child(device_t dev, device_t child) 476{ 477 int retval; 478 479 retval = bus_print_child_header(dev, child); 480 retval += printf(" at channel %d", 481 (int)(intptr_t)device_get_ivars(child)); 482 retval += bus_print_child_footer(dev, child); 483 484 return (retval); 485} 486 487static int 488mvs_child_location_str(device_t dev, device_t child, char *buf, 489 size_t buflen) 490{ 491 492 snprintf(buf, buflen, "channel=%d", 493 (int)(intptr_t)device_get_ivars(child)); 494 return (0); 495} 496 497static device_method_t mvs_methods[] = { 498 DEVMETHOD(device_probe, mvs_probe), 499 DEVMETHOD(device_attach, mvs_attach), 500 DEVMETHOD(device_detach, mvs_detach), 501 DEVMETHOD(device_suspend, mvs_suspend), 502 DEVMETHOD(device_resume, mvs_resume), 503 DEVMETHOD(bus_print_child, mvs_print_child), 504 DEVMETHOD(bus_alloc_resource, mvs_alloc_resource), 505 DEVMETHOD(bus_release_resource, mvs_release_resource), 506 DEVMETHOD(bus_setup_intr, mvs_setup_intr), 507 DEVMETHOD(bus_teardown_intr,mvs_teardown_intr), 508 DEVMETHOD(bus_child_location_str, mvs_child_location_str), 509 DEVMETHOD(mvs_edma, mvs_edma), 510 { 0, 0 } 511}; 512static driver_t mvs_driver = { 513 "mvs", 514 mvs_methods, 515 sizeof(struct mvs_controller) 516}; 517DRIVER_MODULE(mvs, pci, mvs_driver, mvs_devclass, 0, 0); 518MODULE_VERSION(mvs, 1); 519MODULE_DEPEND(mvs, cam, 1, 1, 1); 520
|