px.c (f9721e07) | px.c (b65731f1) |
---|---|
1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * --- 6 unchanged lines hidden (view full) --- 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22/* | 1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * --- 6 unchanged lines hidden (view full) --- 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22/* |
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. | 23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. |
24 * Use is subject to license terms. 25 */ 26 27#pragma ident "%Z%%M% %I% %E% SMI" 28 29/* 30 * PCI Express nexus driver interface 31 */ --- 5 unchanged lines hidden (view full) --- 37#include <sys/sunddi.h> 38#include <sys/sunndi.h> 39#include <sys/hotplug/pci/pcihp.h> 40#include <sys/ddi_impldefs.h> 41#include <sys/ddi_subrdefs.h> 42#include <sys/spl.h> 43#include <sys/epm.h> 44#include <sys/iommutsb.h> | 24 * Use is subject to license terms. 25 */ 26 27#pragma ident "%Z%%M% %I% %E% SMI" 28 29/* 30 * PCI Express nexus driver interface 31 */ --- 5 unchanged lines hidden (view full) --- 37#include <sys/sunddi.h> 38#include <sys/sunndi.h> 39#include <sys/hotplug/pci/pcihp.h> 40#include <sys/ddi_impldefs.h> 41#include <sys/ddi_subrdefs.h> 42#include <sys/spl.h> 43#include <sys/epm.h> 44#include <sys/iommutsb.h> |
45#include <sys/hotplug/pci/pcihp.h> 46#include <sys/hotplug/pci/pciehpc.h> |
|
45#include "px_obj.h" 46#include <sys/pci_tools.h> 47#include "px_tools_ext.h" 48#include "pcie_pwr.h" 49 50/*LINTLIBRARY*/ 51 52/* 53 * function prototypes for dev ops routines: 54 */ 55static int px_attach(dev_info_t *dip, ddi_attach_cmd_t cmd); 56static int px_detach(dev_info_t *dip, ddi_detach_cmd_t cmd); 57static int px_info(dev_info_t *dip, ddi_info_cmd_t infocmd, 58 void *arg, void **result); 59static int px_pwr_setup(dev_info_t *dip); 60static void px_pwr_teardown(dev_info_t *dip); 61 62/* | 47#include "px_obj.h" 48#include <sys/pci_tools.h> 49#include "px_tools_ext.h" 50#include "pcie_pwr.h" 51 52/*LINTLIBRARY*/ 53 54/* 55 * function prototypes for dev ops routines: 56 */ 57static int px_attach(dev_info_t *dip, ddi_attach_cmd_t cmd); 58static int px_detach(dev_info_t *dip, ddi_detach_cmd_t cmd); 59static int px_info(dev_info_t *dip, ddi_info_cmd_t infocmd, 60 void *arg, void **result); 61static int px_pwr_setup(dev_info_t *dip); 62static void px_pwr_teardown(dev_info_t *dip); 63 64/* |
65 * function prototypes for hotplug routines: 66 */ 67static uint_t px_init_hotplug(px_t *px_p); 68static uint_t px_uninit_hotplug(dev_info_t *dip); 69 70/* |
|
63 * bus ops and dev ops structures: 64 */ 65static struct bus_ops px_bus_ops = { 66 BUSO_REV, 67 px_map, 68 0, 69 0, 70 0, --- 105 unchanged lines hidden (view full) --- 176 177/* ARGSUSED */ 178static int 179px_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result) 180{ 181 int instance = getminor((dev_t)arg); 182 px_t *px_p = INST_TO_STATE(instance); 183 | 71 * bus ops and dev ops structures: 72 */ 73static struct bus_ops px_bus_ops = { 74 BUSO_REV, 75 px_map, 76 0, 77 0, 78 0, --- 105 unchanged lines hidden (view full) --- 184 185/* ARGSUSED */ 186static int 187px_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result) 188{ 189 int instance = getminor((dev_t)arg); 190 px_t *px_p = INST_TO_STATE(instance); 191 |
184#ifdef HOTPLUG | |
185 /* 186 * Allow hotplug to deal with ones it manages 187 * Hot Plug will be done later. 188 */ | 192 /* 193 * Allow hotplug to deal with ones it manages 194 * Hot Plug will be done later. 195 */ |
189 if (px_p && (px_p->hotplug_capable == B_TRUE)) | 196 if (px_p && (px_p->px_dev_caps & PX_HOTPLUG_CAPABLE)) |
190 return (pcihp_info(dip, infocmd, arg, result)); | 197 return (pcihp_info(dip, infocmd, arg, result)); |
191#endif /* HOTPLUG */ | |
192 193 /* non-hotplug or not attached */ 194 switch (infocmd) { 195 case DDI_INFO_DEVT2INSTANCE: 196 *result = (void *)(intptr_t)instance; 197 return (DDI_SUCCESS); 198 199 case DDI_INFO_DEVT2DEVINFO: --- 34 unchanged lines hidden (view full) --- 234 goto err_bad_px_softstate; 235 } 236 px_p = INST_TO_STATE(instance); 237 px_p->px_dip = dip; 238 mutex_init(&px_p->px_mutex, NULL, MUTEX_DRIVER, NULL); 239 px_p->px_soft_state = PX_SOFT_STATE_CLOSED; 240 px_p->px_open_count = 0; 241 | 198 199 /* non-hotplug or not attached */ 200 switch (infocmd) { 201 case DDI_INFO_DEVT2INSTANCE: 202 *result = (void *)(intptr_t)instance; 203 return (DDI_SUCCESS); 204 205 case DDI_INFO_DEVT2DEVINFO: --- 34 unchanged lines hidden (view full) --- 240 goto err_bad_px_softstate; 241 } 242 px_p = INST_TO_STATE(instance); 243 px_p->px_dip = dip; 244 mutex_init(&px_p->px_mutex, NULL, MUTEX_DRIVER, NULL); 245 px_p->px_soft_state = PX_SOFT_STATE_CLOSED; 246 px_p->px_open_count = 0; 247 |
248 (void) ddi_prop_update_string(DDI_DEV_T_NONE, dip, 249 "device_type", "pciex"); |
|
242 /* 243 * Get key properties of the pci bridge node and 244 * determine it's type (psycho, schizo, etc ...). 245 */ 246 if (px_get_props(px_p, dip) == DDI_FAILURE) 247 goto err_bad_px_prop; 248 249 if ((px_fm_attach(px_p)) != DDI_SUCCESS) --- 38 unchanged lines hidden (view full) --- 288 289 /* 290 * All of the error handlers have been registered 291 * by now so it's time to activate the interrupt. 292 */ 293 if ((ret = px_err_add_intr(&px_p->px_fault)) != DDI_SUCCESS) 294 goto err_bad_pec_add_intr; 295 | 250 /* 251 * Get key properties of the pci bridge node and 252 * determine it's type (psycho, schizo, etc ...). 253 */ 254 if (px_get_props(px_p, dip) == DDI_FAILURE) 255 goto err_bad_px_prop; 256 257 if ((px_fm_attach(px_p)) != DDI_SUCCESS) --- 38 unchanged lines hidden (view full) --- 296 297 /* 298 * All of the error handlers have been registered 299 * by now so it's time to activate the interrupt. 300 */ 301 if ((ret = px_err_add_intr(&px_p->px_fault)) != DDI_SUCCESS) 302 goto err_bad_pec_add_intr; 303 |
304 (void) px_init_hotplug(px_p); 305 |
|
296 /* 297 * Create the "devctl" node for hotplug and pcitool support. 298 * For non-hotplug bus, we still need ":devctl" to 299 * support DEVCTL_DEVICE_* and DEVCTL_BUS_* ioctls. 300 */ 301 if (ddi_create_minor_node(dip, "devctl", S_IFCHR, 302 PCIHP_AP_MINOR_NUM(instance, PCIHP_DEVCTL_MINOR), 303 DDI_NT_NEXUS, 0) != DDI_SUCCESS) { --- 111 unchanged lines hidden (view full) --- 415 case DDI_DETACH: 416 DBG(DBG_DETACH, dip, "DDI_DETACH\n"); 417 418 /* 419 * remove cpr callback 420 */ 421 px_cpr_rem_callb(px_p); 422 | 306 /* 307 * Create the "devctl" node for hotplug and pcitool support. 308 * For non-hotplug bus, we still need ":devctl" to 309 * support DEVCTL_DEVICE_* and DEVCTL_BUS_* ioctls. 310 */ 311 if (ddi_create_minor_node(dip, "devctl", S_IFCHR, 312 PCIHP_AP_MINOR_NUM(instance, PCIHP_DEVCTL_MINOR), 313 DDI_NT_NEXUS, 0) != DDI_SUCCESS) { --- 111 unchanged lines hidden (view full) --- 425 case DDI_DETACH: 426 DBG(DBG_DETACH, dip, "DDI_DETACH\n"); 427 428 /* 429 * remove cpr callback 430 */ 431 px_cpr_rem_callb(px_p); 432 |
423#ifdef HOTPLUG 424 /* 425 * Hot plug will be done later. 426 */ 427 if (px_p->hotplug_capable == B_TRUE) { 428 if (pxhp_uninit(dip) == DDI_FAILURE) { | 433 if (px_p->px_dev_caps & PX_HOTPLUG_CAPABLE) 434 if (px_uninit_hotplug(dip) != DDI_SUCCESS) { |
429 mutex_exit(&px_p->px_mutex); 430 return (DDI_FAILURE); 431 } | 435 mutex_exit(&px_p->px_mutex); 436 return (DDI_FAILURE); 437 } |
432 } 433#endif /* HOTPLUG */ | |
434 435 /* 436 * things which used to be done in obj_destroy 437 * are now in-lined here. 438 */ 439 440 px_p->px_state = PX_DETACHED; 441 --- 83 unchanged lines hidden (view full) --- 525 } 526 /* No support for device PM. We are always at full power */ 527 pwr_p->pwr_func_lvl = PM_LEVEL_D0; 528 529 mutex_init(&px_p->px_l23ready_lock, NULL, MUTEX_DRIVER, 530 DDI_INTR_PRI(px_pwr_pil)); 531 cv_init(&px_p->px_l23ready_cv, NULL, CV_DRIVER, NULL); 532 | 438 439 /* 440 * things which used to be done in obj_destroy 441 * are now in-lined here. 442 */ 443 444 px_p->px_state = PX_DETACHED; 445 --- 83 unchanged lines hidden (view full) --- 529 } 530 /* No support for device PM. We are always at full power */ 531 pwr_p->pwr_func_lvl = PM_LEVEL_D0; 532 533 mutex_init(&px_p->px_l23ready_lock, NULL, MUTEX_DRIVER, 534 DDI_INTR_PRI(px_pwr_pil)); 535 cv_init(&px_p->px_l23ready_cv, NULL, CV_DRIVER, NULL); 536 |
537 538 |
|
533 /* Initilize handle */ 534 hdl.ih_cb_arg1 = px_p; 535 hdl.ih_cb_arg2 = NULL; 536 hdl.ih_ver = DDI_INTR_VERSION; 537 hdl.ih_state = DDI_IHDL_STATE_ALLOC; 538 hdl.ih_dip = dip; 539 hdl.ih_inum = 0; 540 hdl.ih_pri = px_pwr_pil; --- 758 unchanged lines hidden (view full) --- 1299 break; 1300 default: 1301 ret = DDI_ENOTSUP; 1302 break; 1303 } 1304 1305 return (ret); 1306} | 539 /* Initilize handle */ 540 hdl.ih_cb_arg1 = px_p; 541 hdl.ih_cb_arg2 = NULL; 542 hdl.ih_ver = DDI_INTR_VERSION; 543 hdl.ih_state = DDI_IHDL_STATE_ALLOC; 544 hdl.ih_dip = dip; 545 hdl.ih_inum = 0; 546 hdl.ih_pri = px_pwr_pil; --- 758 unchanged lines hidden (view full) --- 1305 break; 1306 default: 1307 ret = DDI_ENOTSUP; 1308 break; 1309 } 1310 1311 return (ret); 1312} |
1313 1314static uint_t 1315px_init_hotplug(px_t *px_p) 1316{ 1317 px_bus_range_t bus_range; 1318 dev_info_t *dip; 1319 pciehpc_regops_t regops; 1320 1321 dip = px_p->px_dip; 1322 1323 if (ddi_prop_exists(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 1324 "hotplug-capable") == 0) 1325 return (DDI_FAILURE); 1326 1327 /* 1328 * Before initializing hotplug - open up bus range. The busra 1329 * module will initialize its pool of bus numbers from this. 1330 * "busra" will be the agent that keeps track of them during 1331 * hotplug. Also, note, that busra will remove any bus numbers 1332 * already in use from boot time. 1333 */ 1334 if (ddi_prop_exists(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 1335 "bus-range") == 0) { 1336 cmn_err(CE_WARN, "%s%d: bus-range not found\n", 1337 ddi_driver_name(dip), ddi_get_instance(dip)); 1338#ifdef DEBUG 1339 bus_range.lo = 0x0; 1340 bus_range.hi = 0xff; 1341 1342 if (ndi_prop_update_int_array(DDI_DEV_T_NONE, 1343 dip, "bus-range", (int *)&bus_range, 2) 1344 != DDI_PROP_SUCCESS) { 1345 return (DDI_FAILURE); 1346 } 1347#else 1348 return (DDI_FAILURE); 1349#endif 1350 } 1351 1352 if (px_lib_hotplug_init(dip, (void *)®ops) != DDI_SUCCESS) 1353 return (DDI_FAILURE); 1354 1355 if (pciehpc_init(dip, ®ops) != DDI_SUCCESS) { 1356 px_lib_hotplug_uninit(dip); 1357 return (DDI_FAILURE); 1358 } 1359 1360 if (pcihp_init(dip) != DDI_SUCCESS) { 1361 (void) pciehpc_uninit(dip); 1362 px_lib_hotplug_uninit(dip); 1363 return (DDI_FAILURE); 1364 } 1365 1366 if (pcihp_get_cb_ops() != NULL) { 1367 DBG(DBG_ATTACH, dip, "%s%d hotplug enabled", 1368 ddi_driver_name(dip), ddi_get_instance(dip)); 1369 px_p->px_dev_caps |= PX_HOTPLUG_CAPABLE; 1370 } 1371 1372 return (DDI_SUCCESS); 1373} 1374 1375static uint_t 1376px_uninit_hotplug(dev_info_t *dip) 1377{ 1378 if (pcihp_uninit(dip) != DDI_SUCCESS) 1379 return (DDI_FAILURE); 1380 1381 if (pciehpc_uninit(dip) != DDI_SUCCESS) 1382 return (DDI_FAILURE); 1383 1384 px_lib_hotplug_uninit(dip); 1385 1386 return (DDI_SUCCESS); 1387} |
|