1 /*- 2 * Copyright 2016-2025 Microchip Technology, Inc. and/or its subsidiaries. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 * SUCH DAMAGE. 24 */ 25 26 27 /* 28 * Driver for the Microchip Smart storage controllers 29 */ 30 31 #include "smartpqi_includes.h" 32 #include "smartpqi_controllers.h" 33 34 CTASSERT(BSD_SUCCESS == PQI_STATUS_SUCCESS); 35 36 /* 37 * Logging levels global 38 */ 39 unsigned long logging_level = PQISRC_LOG_LEVEL; 40 41 /* 42 * Function to identify the installed adapter. 43 */ 44 static struct pqi_ident * 45 pqi_find_ident(device_t dev) 46 { 47 struct pqi_ident *m; 48 u_int16_t vendid, devid, sub_vendid, sub_devid; 49 static long AllowWildcards = 0xffffffff; 50 int result; 51 52 #ifdef DEVICE_HINT 53 if (AllowWildcards == 0xffffffff) 54 { 55 result = resource_long_value("smartpqi", 0, "allow_wildcards", &AllowWildcards); 56 57 /* the default case if the hint is not found is to allow wildcards */ 58 if (result != DEVICE_HINT_SUCCESS) { 59 AllowWildcards = 1; 60 } 61 } 62 63 #endif 64 65 vendid = pci_get_vendor(dev); 66 devid = pci_get_device(dev); 67 sub_vendid = pci_get_subvendor(dev); 68 sub_devid = pci_get_subdevice(dev); 69 70 for (m = pqi_identifiers; m->vendor != 0; m++) { 71 if ((m->vendor == vendid) && (m->device == devid) && 72 (m->subvendor == sub_vendid) && 73 (m->subdevice == sub_devid)) { 74 return (m); 75 } 76 } 77 78 for (m = pqi_family_identifiers; m->vendor != 0; m++) { 79 if ((m->vendor == vendid) && (m->device == devid)) { 80 if (AllowWildcards != 0) 81 { 82 DBG_NOTE("Controller device ID matched using wildcards\n"); 83 return (m); 84 } 85 else 86 { 87 DBG_NOTE("Controller not probed because device ID wildcards are disabled\n") 88 return (NULL); 89 } 90 } 91 } 92 93 return (NULL); 94 } 95 96 /* 97 * Determine whether this is one of our supported adapters. 98 */ 99 static int 100 smartpqi_probe(device_t dev) 101 { 102 struct pqi_ident *id; 103 104 if ((id = pqi_find_ident(dev)) != NULL) { 105 device_set_desc(dev, id->desc); 106 return(BUS_PROBE_VENDOR); 107 } 108 109 return(ENXIO); 110 } 111 112 /* 113 * Store Bus/Device/Function in softs 114 */ 115 void 116 pqisrc_save_controller_info(struct pqisrc_softstate *softs) 117 { 118 device_t dev = softs->os_specific.pqi_dev; 119 120 softs->bus_id = (uint32_t)pci_get_bus(dev); 121 softs->device_id = (uint32_t)pci_get_device(dev); 122 softs->func_id = (uint32_t)pci_get_function(dev); 123 } 124 125 126 static void read_device_hint_resource(struct pqisrc_softstate *softs, 127 char *keyword, uint32_t *value) 128 { 129 DBG_FUNC("IN\n"); 130 131 long result = 0; 132 133 device_t dev = softs->os_specific.pqi_dev; 134 135 if (resource_long_value("smartpqi", device_get_unit(dev), keyword, &result) == DEVICE_HINT_SUCCESS) { 136 if (result) { 137 /* set resource to 1 for disabling the 138 * firmware feature in device hint file. */ 139 *value = 0; 140 141 } 142 else { 143 /* set resource to 0 for enabling the 144 * firmware feature in device hint file. */ 145 *value = 1; 146 } 147 } 148 else { 149 /* Enabled by default */ 150 *value = 1; 151 } 152 153 DBG_NOTE("SmartPQI Device Hint: %s, Is it enabled = %u\n", keyword, *value); 154 155 DBG_FUNC("OUT\n"); 156 } 157 158 static void read_device_hint_decimal_value(struct pqisrc_softstate *softs, 159 char *keyword, uint32_t *value) 160 { 161 DBG_FUNC("IN\n"); 162 163 long result = 0; 164 165 device_t dev = softs->os_specific.pqi_dev; 166 167 if (resource_long_value("smartpqi", device_get_unit(dev), keyword, &result) == DEVICE_HINT_SUCCESS) { 168 /* Nothing to do here. Value reads 169 * directly from Device.Hint file */ 170 *value = result; 171 } 172 else { 173 /* Set to max to determine the value */ 174 *value = 0XFFFF; 175 } 176 177 DBG_FUNC("OUT\n"); 178 } 179 180 static void smartpqi_read_all_device_hint_file_entries(struct pqisrc_softstate *softs) 181 { 182 uint32_t value = 0; 183 184 DBG_FUNC("IN\n"); 185 186 /* hint.smartpqi.0.stream_disable = "0" */ 187 read_device_hint_resource(softs, STREAM_DETECTION, &value); 188 softs->hint.stream_status = value; 189 190 /* hint.smartpqi.0.sata_unique_wwn_disable = "0" */ 191 read_device_hint_resource(softs, SATA_UNIQUE_WWN, &value); 192 softs->hint.sata_unique_wwn_status = value; 193 194 /* hint.smartpqi.0.aio_raid1_write_disable = "0" */ 195 read_device_hint_resource(softs, AIO_RAID1_WRITE_BYPASS, &value); 196 softs->hint.aio_raid1_write_status = value; 197 198 /* hint.smartpqi.0.aio_raid5_write_disable = "0" */ 199 read_device_hint_resource(softs, AIO_RAID5_WRITE_BYPASS, &value); 200 softs->hint.aio_raid5_write_status = value; 201 202 /* hint.smartpqi.0.aio_raid6_write_disable = "0" */ 203 read_device_hint_resource(softs, AIO_RAID6_WRITE_BYPASS, &value); 204 softs->hint.aio_raid6_write_status = value; 205 206 /* hint.smartpqi.0.queue_depth = "0" */ 207 read_device_hint_decimal_value(softs, ADAPTER_QUEUE_DEPTH, &value); 208 softs->hint.queue_depth = value; 209 210 /* hint.smartpqi.0.sg_count = "0" */ 211 read_device_hint_decimal_value(softs, SCATTER_GATHER_COUNT, &value); 212 softs->hint.sg_segments = value; 213 214 DBG_FUNC("IN\n"); 215 } 216 217 /* Get the driver parameter tunables. */ 218 static void 219 smartpqi_get_tunables(void) 220 { 221 /* 222 * Temp variable used to get the value from loader.conf. 223 * Initializing it with the current logging level value. 224 */ 225 unsigned long logging_level_temp = PQISRC_LOG_LEVEL; 226 227 TUNABLE_ULONG_FETCH("hw.smartpqi.debug_level", &logging_level_temp); 228 229 DBG_SET_LOGGING_LEVEL(logging_level_temp); 230 } 231 232 /* 233 * Allocate resources for our device, set up the bus interface. 234 * Initialize the PQI related functionality, scan devices, register sim to 235 * upper layer, create management interface device node etc. 236 */ 237 static int 238 smartpqi_attach(device_t dev) 239 { 240 struct pqisrc_softstate *softs; 241 struct pqi_ident *id = NULL; 242 int error = BSD_SUCCESS; 243 u_int32_t command = 0, i = 0; 244 int card_index = device_get_unit(dev); 245 rcb_t *rcbp = NULL; 246 247 /* 248 * Initialize softc. 249 */ 250 softs = device_get_softc(dev); 251 252 if (!softs) { 253 printf("Could not get softc\n"); 254 error = EINVAL; 255 goto out; 256 } 257 memset(softs, 0, sizeof(*softs)); 258 softs->os_specific.pqi_dev = dev; 259 260 smartpqi_get_tunables(); 261 262 DBG_FUNC("IN\n"); 263 264 /* assume failure is 'not configured' */ 265 error = ENXIO; 266 267 /* 268 * Verify that the adapter is correctly set up in PCI space. 269 */ 270 pci_enable_busmaster(softs->os_specific.pqi_dev); 271 command = pci_read_config(softs->os_specific.pqi_dev, PCIR_COMMAND, 2); 272 if ((command & PCIM_CMD_MEMEN) == 0) { 273 DBG_ERR("memory window not available command = %d\n", command); 274 error = ENXIO; 275 goto out; 276 } 277 278 /* 279 * Detect the hardware interface version, set up the bus interface 280 * indirection. 281 */ 282 id = pqi_find_ident(dev); 283 if (!id) { 284 DBG_ERR("NULL return value from pqi_find_ident\n"); 285 goto out; 286 } 287 288 softs->os_specific.pqi_hwif = id->hwif; 289 290 switch(softs->os_specific.pqi_hwif) { 291 case PQI_HWIF_SRCV: 292 DBG_INFO("set hardware up for PMC SRCv for %p\n", softs); 293 break; 294 default: 295 softs->os_specific.pqi_hwif = PQI_HWIF_UNKNOWN; 296 DBG_ERR("unknown hardware type\n"); 297 error = ENXIO; 298 goto out; 299 } 300 301 pqisrc_save_controller_info(softs); 302 303 /* 304 * Allocate the PCI register window. 305 */ 306 softs->os_specific.pqi_regs_rid0 = PCIR_BAR(0); 307 if ((softs->os_specific.pqi_regs_res0 = 308 bus_alloc_resource_any(softs->os_specific.pqi_dev, SYS_RES_MEMORY, 309 &softs->os_specific.pqi_regs_rid0, RF_ACTIVE)) == NULL) { 310 DBG_ERR("couldn't allocate register window 0\n"); 311 /* assume failure is 'out of memory' */ 312 error = ENOMEM; 313 goto out; 314 } 315 316 bus_get_resource_start(softs->os_specific.pqi_dev, SYS_RES_MEMORY, 317 softs->os_specific.pqi_regs_rid0); 318 319 softs->pci_mem_handle.pqi_btag = rman_get_bustag(softs->os_specific.pqi_regs_res0); 320 softs->pci_mem_handle.pqi_bhandle = rman_get_bushandle(softs->os_specific.pqi_regs_res0); 321 /* softs->pci_mem_base_vaddr = (uintptr_t)rman_get_virtual(softs->os_specific.pqi_regs_res0); */ 322 softs->pci_mem_base_vaddr = (char *)rman_get_virtual(softs->os_specific.pqi_regs_res0); 323 324 /* 325 * Allocate the parent bus DMA tag appropriate for our PCI interface. 326 * 327 * Note that some of these controllers are 64-bit capable. 328 */ 329 if (bus_dma_tag_create(bus_get_dma_tag(dev), /* parent */ 330 PAGE_SIZE, 0, /* algnmnt, boundary */ 331 BUS_SPACE_MAXADDR,/* lowaddr */ 332 BUS_SPACE_MAXADDR, /* highaddr */ 333 NULL, NULL, /* filter, filterarg */ 334 BUS_SPACE_MAXSIZE, /* maxsize */ 335 BUS_SPACE_UNRESTRICTED, /* nsegments */ 336 BUS_SPACE_MAXSIZE, /* maxsegsize */ 337 0, /* flags */ 338 NULL, NULL, /* No locking needed */ 339 &softs->os_specific.pqi_parent_dmat)) { 340 DBG_ERR("can't allocate parent DMA tag\n"); 341 /* assume failure is 'out of memory' */ 342 error = ENOMEM; 343 goto dma_out; 344 } 345 346 softs->os_specific.sim_registered = FALSE; 347 softs->os_name = "FreeBSD "; 348 349 smartpqi_read_all_device_hint_file_entries(softs); 350 351 /* Initialize the PQI library */ 352 error = pqisrc_init(softs); 353 if (error != PQI_STATUS_SUCCESS) { 354 DBG_ERR("Failed to initialize pqi lib error = %d\n", error); 355 error = ENXIO; 356 goto out; 357 } 358 else { 359 error = BSD_SUCCESS; 360 } 361 362 mtx_init(&softs->os_specific.cam_lock, "cam_lock", NULL, MTX_DEF); 363 softs->os_specific.mtx_init = TRUE; 364 mtx_init(&softs->os_specific.map_lock, "map_lock", NULL, MTX_DEF); 365 366 callout_init(&softs->os_specific.wellness_periodic, 1); 367 callout_init(&softs->os_specific.heartbeat_timeout_id, 1); 368 369 /* 370 * Create DMA tag for mapping buffers into controller-addressable space. 371 */ 372 if (bus_dma_tag_create(softs->os_specific.pqi_parent_dmat,/* parent */ 373 1, 0, /* algnmnt, boundary */ 374 BUS_SPACE_MAXADDR, /* lowaddr */ 375 BUS_SPACE_MAXADDR, /* highaddr */ 376 NULL, NULL, /* filter, filterarg */ 377 (bus_size_t)softs->pqi_cap.max_sg_elem*PAGE_SIZE,/* maxsize */ 378 softs->pqi_cap.max_sg_elem, /* nsegments */ 379 BUS_SPACE_MAXSIZE, /* maxsegsize */ 380 BUS_DMA_ALLOCNOW, /* flags */ 381 busdma_lock_mutex, /* lockfunc */ 382 &softs->os_specific.map_lock, /* lockfuncarg*/ 383 &softs->os_specific.pqi_buffer_dmat)) { 384 DBG_ERR("can't allocate buffer DMA tag for pqi_buffer_dmat\n"); 385 return (ENOMEM); 386 } 387 388 rcbp = &softs->rcb[1]; 389 for( i = 1; i <= softs->pqi_cap.max_outstanding_io; i++, rcbp++ ) { 390 if ((error = bus_dmamap_create(softs->os_specific.pqi_buffer_dmat, 0, &rcbp->cm_datamap)) != 0) { 391 DBG_ERR("Cant create datamap for buf @" 392 "rcbp = %p maxio = %u error = %d\n", 393 rcbp, softs->pqi_cap.max_outstanding_io, error); 394 goto dma_out; 395 } 396 } 397 398 os_start_heartbeat_timer((void *)softs); /* Start the heart-beat timer */ 399 callout_reset(&softs->os_specific.wellness_periodic, 120 * hz, 400 os_wellness_periodic, softs); 401 402 error = pqisrc_scan_devices(softs); 403 if (error != PQI_STATUS_SUCCESS) { 404 DBG_ERR("Failed to scan lib error = %d\n", error); 405 error = ENXIO; 406 goto out; 407 } 408 else { 409 error = BSD_SUCCESS; 410 } 411 412 error = register_sim(softs, card_index); 413 if (error) { 414 DBG_ERR("Failed to register sim index = %d error = %d\n", 415 card_index, error); 416 goto out; 417 } 418 419 smartpqi_target_rescan(softs); 420 421 TASK_INIT(&softs->os_specific.event_task, 0, pqisrc_event_worker,softs); 422 423 error = create_char_dev(softs, card_index); 424 if (error) { 425 DBG_ERR("Failed to register character device index=%d r=%d\n", 426 card_index, error); 427 goto out; 428 } 429 430 goto out; 431 432 dma_out: 433 if (softs->os_specific.pqi_regs_res0 != NULL) 434 bus_release_resource(softs->os_specific.pqi_dev, SYS_RES_MEMORY, 435 softs->os_specific.pqi_regs_rid0, 436 softs->os_specific.pqi_regs_res0); 437 out: 438 DBG_FUNC("OUT error = %d\n", error); 439 440 return(error); 441 } 442 443 /* 444 * Deallocate resources for our device. 445 */ 446 static int 447 smartpqi_detach(device_t dev) 448 { 449 struct pqisrc_softstate *softs = device_get_softc(dev); 450 int rval = BSD_SUCCESS; 451 452 DBG_FUNC("IN\n"); 453 454 if (softs == NULL) 455 return ENXIO; 456 457 /* kill the periodic event */ 458 callout_drain(&softs->os_specific.wellness_periodic); 459 /* Kill the heart beat event */ 460 callout_drain(&softs->os_specific.heartbeat_timeout_id); 461 462 if (!pqisrc_ctrl_offline(softs)) { 463 rval = pqisrc_flush_cache(softs, PQISRC_NONE_CACHE_FLUSH_ONLY); 464 if (rval != PQI_STATUS_SUCCESS) { 465 DBG_ERR("Unable to flush adapter cache! rval = %d\n", rval); 466 rval = EIO; 467 } else { 468 rval = BSD_SUCCESS; 469 } 470 } 471 472 destroy_char_dev(softs); 473 pqisrc_uninit(softs); 474 deregister_sim(softs); 475 pci_release_msi(dev); 476 477 DBG_FUNC("OUT\n"); 478 479 return rval; 480 } 481 482 /* 483 * Bring the controller to a quiescent state, ready for system suspend. 484 */ 485 static int 486 smartpqi_suspend(device_t dev) 487 { 488 struct pqisrc_softstate *softs = device_get_softc(dev); 489 490 DBG_FUNC("IN\n"); 491 492 if (softs == NULL) 493 return ENXIO; 494 495 DBG_INFO("Suspending the device %p\n", softs); 496 softs->os_specific.pqi_state |= SMART_STATE_SUSPEND; 497 498 DBG_FUNC("OUT\n"); 499 500 return BSD_SUCCESS; 501 } 502 503 /* 504 * Bring the controller back to a state ready for operation. 505 */ 506 static int 507 smartpqi_resume(device_t dev) 508 { 509 struct pqisrc_softstate *softs = device_get_softc(dev); 510 511 DBG_FUNC("IN\n"); 512 513 if (softs == NULL) 514 return ENXIO; 515 516 softs->os_specific.pqi_state &= ~SMART_STATE_SUSPEND; 517 518 DBG_FUNC("OUT\n"); 519 520 return BSD_SUCCESS; 521 } 522 523 /* 524 * Do whatever is needed during a system shutdown. 525 */ 526 static int 527 smartpqi_shutdown(device_t dev) 528 { 529 struct pqisrc_softstate *softs = device_get_softc(dev); 530 int bsd_status = BSD_SUCCESS; 531 int pqi_status; 532 533 DBG_FUNC("IN\n"); 534 535 if (softs == NULL) 536 return ENXIO; 537 538 if (pqisrc_ctrl_offline(softs)) 539 return BSD_SUCCESS; 540 541 pqi_status = pqisrc_flush_cache(softs, PQISRC_SHUTDOWN); 542 if (pqi_status != PQI_STATUS_SUCCESS) { 543 DBG_ERR("Unable to flush adapter cache! rval = %d\n", pqi_status); 544 bsd_status = EIO; 545 } 546 547 DBG_FUNC("OUT\n"); 548 549 return bsd_status; 550 } 551 552 553 /* 554 * PCI bus interface. 555 */ 556 static device_method_t pqi_methods[] = { 557 /* Device interface */ 558 DEVMETHOD(device_probe, smartpqi_probe), 559 DEVMETHOD(device_attach, smartpqi_attach), 560 DEVMETHOD(device_detach, smartpqi_detach), 561 DEVMETHOD(device_suspend, smartpqi_suspend), 562 DEVMETHOD(device_resume, smartpqi_resume), 563 DEVMETHOD(device_shutdown, smartpqi_shutdown), 564 DEVMETHOD_END 565 }; 566 567 static driver_t smartpqi_pci_driver = { 568 "smartpqi", 569 pqi_methods, 570 sizeof(struct pqisrc_softstate) 571 }; 572 573 DRIVER_MODULE(smartpqi, pci, smartpqi_pci_driver, 0, 0); 574 575 MODULE_DEPEND(smartpqi, pci, 1, 1, 1); 576