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 (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25 /*
26 * Copyright 2012 Garrett D'Amore <garrett@damore.org>. All rights reserved.
27 */
28
29
30 /*
31 * Intel 21554 PCI to PCI bus bridge nexus driver for sun4u platforms.
32 * Please note that 21554 is not a transparent bridge.
33 * This driver can be used when the 21554 bridge is used like a
34 * transparent bridge. The host OBP or the OS PCI Resource Allocator
35 * (during a hotplug/hotswap operation) must represent this device
36 * as a nexus and do the device tree representation of the child
37 * nodes underneath.
38 * Interrupt routing of the children must be done as per the PCI
39 * specifications recommendation similar to that of a transparent
40 * bridge.
41 * Address translations from secondary across primary can be 1:1
42 * or non 1:1. Currently only 1:1 translations are supported.
43 * Configuration cycles are indirect. Memory and IO cycles are direct.
44 */
45
46 /*
47 * INCLUDES
48 */
49 #include <sys/stat.h>
50 #include <sys/conf.h>
51 #include <sys/kmem.h>
52 #include <sys/debug.h>
53 #include <sys/modctl.h>
54 #include <sys/autoconf.h>
55 #include <sys/ddi_impldefs.h>
56 #include <sys/ddi_subrdefs.h>
57 #include <sys/pci.h>
58 #include <sys/pci/pci_nexus.h>
59 #include <sys/pci/pci_regs.h>
60 #include <sys/pci/db21554_config.h> /* 21554 configuration space registers */
61 #include <sys/pci/db21554_csr.h> /* 21554 control status register layout */
62 #include <sys/pci/db21554_ctrl.h> /* driver private control structure */
63 #include <sys/pci/db21554_debug.h> /* driver debug declarations */
64 #include <sys/ddi.h>
65 #include <sys/sunddi.h>
66 #include <sys/sunndi.h>
67 #include <sys/fm/protocol.h>
68 #include <sys/ddifm.h>
69 #include <sys/promif.h>
70 #include <sys/file.h>
71 #include <sys/hotplug/pci/pcihp.h>
72
73 /*
74 * DEFINES.
75 */
76 #define DB_DEBUG
77 #define DB_MODINFO_DESCRIPTION "Intel/21554 pci-pci nexus"
78 #define DB_DVMA_START 0xc0000000
79 #define DB_DVMA_LEN 0x20000000
80
81 #ifdef DB_DEBUG
82 /* ioctl definitions */
83 #define DB_PCI_READ_CONF_HEADER 1
84 #define DEF_INVALID_REG_VAL -1
85
86 /* Default values for secondary cache line and latency timer */
87 #define DB_SEC_LATENCY_TIMER_VAL 0x40
88 #define DB_SEC_CACHELN_SIZE_VAL 0x10
89
90 /* complete chip status information */
91 typedef struct db_pci_data {
92 char name[256];
93 uint32_t instance;
94 db_pci_header_t pri_hdr;
95 db_pci_header_t sec_hdr;
96 db_conf_regs_t conf_regs;
97 } db_pci_data_t;
98 #endif
99
100 /*
101 * LOCALS
102 */
103
104 /*
105 * The next set of variables are control parameters for debug purposes only.
106 * Changing the default values as assigned below are not recommended.
107 * In some cases, the non-default values are mostly application specific and
108 * hence may not have been tested yet.
109 *
110 * db_conf_map_mode : specifies the access method used for generating
111 * configuration cycles. Default value indicates
112 * the indirect configuration method.
113 * db_io_map_mode : specifies the access method used for generating
114 * IO cycles. Default value indicates the direct
115 * method.
116 * db_pci_own_wait : For indirect cycles, indicates the wait period
117 * for acquiring the bus, when the bus is busy.
118 * db_pci_release_wait:For indirect cycles, indicates the wait period
119 * for releasing the bus when the bus is busy.
120 * db_pci_max_wait : max. wait time when bus is busy for indirect cycles
121 * db_set_latency_timer_register :
122 * when 1, the driver overwrites the OBP assigned
123 * latency timer register setting for every child
124 * device during child initialization.
125 * db_set_cache_line_size_register :
126 * when 1, the driver overwrites the OBP assigned
127 * cache line register setting for every child
128 * device during child initialization.
129 * db_use_config_own_bit:
130 * when 1, the driver will use the "config own bit"
131 * for accessing the configuration address and data
132 * registers.
133 */
134 static uint32_t db_pci_own_wait = DB_PCI_WAIT_MS;
135 static uint32_t db_pci_release_wait = DB_PCI_WAIT_MS;
136 static uint32_t db_pci_max_wait = DB_PCI_TIMEOUT;
137 static uint32_t db_conf_map_mode = DB_CONF_MAP_INDIRECT_CONF;
138 static uint32_t db_io_map_mode = DB_IO_MAP_DIRECT;
139 static uint32_t db_set_latency_timer_register = 1;
140 static uint32_t db_set_cache_line_size_register = 1;
141 static uint32_t db_use_config_own_bit = 0;
142
143 /*
144 * Properties that can be set via .conf files.
145 */
146
147 /*
148 * By default, we forward SERR# from secondary to primary. This behavior
149 * can be controlled via a property "serr-fwd-enable", type integer.
150 * Values are 0 or 1.
151 * 0 means 'do not forward SERR#'.
152 * 1 means forwards SERR# to the host. Should be the default.
153 */
154 static uint32_t db_serr_fwd_enable = 1;
155
156 /*
157 * The next set of parameters are performance tuning parameters.
158 * These are in the form of properties settable through a .conf file.
159 * In case if the properties are absent the following defaults are assumed.
160 * These initial default values can be overwritten via /etc/system also.
161 *
162 * -1 means no setting is done ie. we either get OBP assigned value
163 * or reset values (at hotplug time for example).
164 */
165
166 /* primary latency timer: property "p-latency-timer" : type integer */
167 static int8_t p_latency_timer = DEF_INVALID_REG_VAL;
168
169 /* secondary latency timer: property "s-latency-timer": type integer */
170 /*
171 * Currently on the secondary side the latency timer is not
172 * set by the serial PROM which causes performance degradation.
173 * Set the secondary latency timer register.
174 */
175 static int8_t s_latency_timer = DB_SEC_LATENCY_TIMER_VAL;
176
177 /* primary cache line size: property "p-cache-line-size" : type integer */
178 static int8_t p_cache_line_size = DEF_INVALID_REG_VAL;
179
180 /* secondary cache line size: property "s-cache-line-size" : type integer */
181 /*
182 * Currently on the secondary side the cache line size is not
183 * set by the serial PROM which causes performance degradation.
184 * Set the secondary cache line size register.
185 */
186 static int8_t s_cache_line_size = DB_SEC_CACHELN_SIZE_VAL;
187
188 /*
189 * control primary posted write queue threshold limit:
190 * property "p-pwrite-threshold" : type integer : values are 0 or 1.
191 * 1 enables control. 0 does not, and is the default reset value.
192 */
193 static int8_t p_pwrite_threshold = DEF_INVALID_REG_VAL;
194
195 /*
196 * control secondary posted write queue threshold limit:
197 * property "s-pwrite-threshold" : type integer : values are 0 or 1.
198 * 1 enables control. 0 does not, and is the default reset value.
199 */
200 static int8_t s_pwrite_threshold = DEF_INVALID_REG_VAL;
201
202 /*
203 * control read queue threshold for initiating delayed read transaction
204 * on primary bus.
205 * property "p-dread-threshold" : type integer: values are
206 *
207 * 0 : reset value, default behavior: at least 8DWords free for all MR
208 * 1 : reserved
209 * 2 : at least one cache line free for MRL and MRM, 8 DWords free for MR
210 * 3 : at least one cache line free for all MR
211 */
212 static int8_t p_dread_threshold = DEF_INVALID_REG_VAL;
213
214 /*
215 * control read queue threshold for initiating delayed read transaction
216 * on secondary bus.
217 * property "s-dread-threshold" : type integer: values are
218 *
219 * 0 : reset value, default behavior: at least 8DWords free for all MR
220 * 1 : reserved
221 * 2 : at least one cache line free for MRL and MRM, 8 DWords free for MR
222 * 3 : at least one cache line free for all MR
223 */
224 static int8_t s_dread_threshold = DEF_INVALID_REG_VAL;
225
226 /*
227 * control how 21554 issues delayed transactions on the target bus.
228 * property "delayed-trans-order" : type integer: values are 0 or 1.
229 * 1 means repeat transaction on same target on target retries.
230 * 0 is the reset/default value, and means enable round robin based
231 * reads on other targets in read queue on any target retries.
232 */
233 static int8_t delayed_trans_order = DEF_INVALID_REG_VAL;
234
235 /*
236 * In case if the system DVMA information is not available, as it is
237 * prior to s28q1, the system dvma range can be set via these parameters.
238 */
239 static uint32_t db_dvma_start = DB_DVMA_START;
240 static uint32_t db_dvma_len = DB_DVMA_LEN;
241
242 /*
243 * Default command register settings for all PCI nodes this nexus initializes.
244 */
245 static uint16_t db_command_default =
246 PCI_COMM_SERR_ENABLE |
247 PCI_COMM_PARITY_DETECT |
248 PCI_COMM_ME |
249 PCI_COMM_MAE |
250 PCI_COMM_IO |
251 PCI_COMM_BACK2BACK_ENAB |
252 PCI_COMM_MEMWR_INVAL;
253
254 static int db_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
255 static int db_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);
256 static void db_get_perf_parameters(db_ctrl_t *dbp);
257 static void db_set_perf_parameters(db_ctrl_t *dbp);
258 static void db_enable_io(db_ctrl_t *dbp);
259 static void db_orientation(db_ctrl_t *dbp);
260 static void db_set_dvma_range(db_ctrl_t *dbp);
261 static int db_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg,
262 void **result);
263 static int db_pci_map(dev_info_t *, dev_info_t *, ddi_map_req_t *,
264 off_t, off_t, caddr_t *);
265 static int db_ctlops(dev_info_t *, dev_info_t *, ddi_ctl_enum_t,
266 void *, void *);
267 static int db_intr_ops(dev_info_t *dip, dev_info_t *rdip,
268 ddi_intr_op_t intr_op, ddi_intr_handle_impl_t *hdlp,
269 void *result);
270 static dev_info_t *db_get_my_childs_dip(dev_info_t *dip, dev_info_t *rdip);
271 static int db_fm_init_child(dev_info_t *dip, dev_info_t *tdip, int cap,
272 ddi_iblock_cookie_t *ibc);
273 static void db_bus_enter(dev_info_t *dip, ddi_acc_handle_t handle);
274 static void db_bus_exit(dev_info_t *dip, ddi_acc_handle_t handle);
275
276 struct bus_ops db_bus_ops = {
277 BUSO_REV,
278 db_pci_map,
279 0,
280 0,
281 0,
282 i_ddi_map_fault,
283 0,
284 ddi_dma_allochdl,
285 ddi_dma_freehdl,
286 ddi_dma_bindhdl,
287 ddi_dma_unbindhdl,
288 ddi_dma_flush,
289 ddi_dma_win,
290 ddi_dma_mctl,
291 db_ctlops,
292 ddi_bus_prop_op,
293 ndi_busop_get_eventcookie,
294 ndi_busop_add_eventcall,
295 ndi_busop_remove_eventcall,
296 ndi_post_event,
297 0,
298 0,
299 0,
300 db_fm_init_child,
301 NULL,
302 db_bus_enter,
303 db_bus_exit,
304 0,
305 db_intr_ops
306 };
307
308 static int db_open(dev_t *dev_p, int flag, int otyp, cred_t *cred_p);
309 static int db_close(dev_t dev, int flag, int otyp, cred_t *cred_p);
310 static int db_ioctl(dev_t dev, int cmd, intptr_t arg, int flag,
311 cred_t *cred_p, int *rval_p);
312 #ifdef DB_DEBUG
313 static dev_info_t *db_lookup_child_name(db_ctrl_t *dbp, char *name,
314 int instance);
315 static void db_pci_get_header(ddi_acc_handle_t config_handle,
316 db_pci_header_t *ph, off_t hdr_off);
317 static void db_pci_get_conf_regs(ddi_acc_handle_t config_handle,
318 db_conf_regs_t *cr);
319 #endif /* DB_DEBUG */
320
321 #ifdef DEBUG
322 static void
323 db_debug(uint64_t func_id, dev_info_t *dip, char *fmt,
324 uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5);
325 #endif
326
327 static int db_prop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op,
328 int flags, char *name, caddr_t valuep, int *lengthp);
329
330 static struct cb_ops db_cb_ops = {
331 db_open, /* open */
332 db_close, /* close */
333 nulldev, /* strategy */
334 nulldev, /* print */
335 nulldev, /* dump */
336 nulldev, /* read */
337 nulldev, /* write */
338 db_ioctl, /* ioctl */
339 nodev, /* devmap */
340 nodev, /* mmap */
341 nodev, /* segmap */
342 nochpoll, /* poll */
343 db_prop_op, /* cb_prop_op */
344 NULL, /* streamtab */
345 D_NEW | D_MP | D_HOTPLUG, /* Driver compatibility flag */
346 CB_REV, /* rev */
347 nodev, /* int (*cb_aread)() */
348 nodev /* int (*cb_awrite)() */
349 };
350
351 static uint8_t db_ddi_get8(ddi_acc_impl_t *handle, uint8_t *addr);
352 static uint16_t db_ddi_get16(ddi_acc_impl_t *handle, uint16_t *addr);
353 static uint32_t db_ddi_get32(ddi_acc_impl_t *handle, uint32_t *addr);
354 static uint64_t db_ddi_get64(ddi_acc_impl_t *handle, uint64_t *addr);
355 static void db_ddi_put8(ddi_acc_impl_t *handle, uint8_t *addr,
356 uint8_t data);
357 static void db_ddi_put16(ddi_acc_impl_t *handle, uint16_t *addr,
358 uint16_t data);
359 static void db_ddi_put32(ddi_acc_impl_t *handle, uint32_t *addr,
360 uint32_t data);
361 static void db_ddi_put64(ddi_acc_impl_t *handle, uint64_t *addr,
362 uint64_t data);
363 static void db_ddi_rep_get8(ddi_acc_impl_t *handle, uint8_t *host_addr,
364 uint8_t *dev_addr, size_t repcount, uint_t flags);
365 static void db_ddi_rep_get16(ddi_acc_impl_t *handle, uint16_t *host_addr,
366 uint16_t *dev_addr, size_t repcount, uint_t flags);
367 static void db_ddi_rep_get32(ddi_acc_impl_t *handle, uint32_t *host_addr,
368 uint32_t *dev_addr, size_t repcount, uint_t flags);
369 static void db_ddi_rep_get64(ddi_acc_impl_t *handle, uint64_t *host_addr,
370 uint64_t *dev_addr, size_t repcount, uint_t flags);
371 static void db_ddi_rep_put8(ddi_acc_impl_t *handle, uint8_t *host_addr,
372 uint8_t *dev_addr, size_t repcount, uint_t flags);
373 static void db_ddi_rep_put16(ddi_acc_impl_t *handle, uint16_t *host_addr,
374 uint16_t *dev_addr, size_t repcount, uint_t flags);
375 static void db_ddi_rep_put32(ddi_acc_impl_t *handle, uint32_t *host_addr,
376 uint32_t *dev_addr, size_t repcount, uint_t flags);
377 static void db_ddi_rep_put64(ddi_acc_impl_t *handle, uint64_t *host_addr,
378 uint64_t *dev_addr, size_t repcount, uint_t flags);
379
380 static struct dev_ops db_dev_ops = {
381 DEVO_REV, /* devo_rev */
382 0, /* refcnt */
383 db_getinfo, /* info */
384 nulldev, /* identify */
385 nulldev, /* probe */
386 db_attach, /* attach */
387 db_detach, /* detach */
388 nulldev, /* reset */
389 &db_cb_ops, /* driver operations */
390 &db_bus_ops, /* bus operations */
391 ddi_power,
392 ddi_quiesce_not_supported, /* devo_quiesce */
393 };
394
395
396 /*
397 * Module linkage information for the kernel.
398 */
399
400 static struct modldrv modldrv = {
401 &mod_driverops, /* Type of module */
402 DB_MODINFO_DESCRIPTION,
403 &db_dev_ops /* driver ops */
404 };
405
406 static struct modlinkage modlinkage = {
407 MODREV_1,
408 (void *)&modldrv,
409 NULL
410 };
411
412 /* soft state pointer and structure template. */
413 static void *db_state;
414
415 /*
416 * forward function declarations:
417 */
418 static void db_uninitchild(dev_info_t *);
419 static int db_initchild(dev_info_t *child);
420 static int db_create_pci_prop(dev_info_t *child);
421 static int db_save_config_regs(db_ctrl_t *dbp);
422 static int db_restore_config_regs(db_ctrl_t *dbp);
423
424 /*
425 * FMA error callback
426 * Register error handling callback with our parent. We will just call
427 * our children's error callbacks and return their status.
428 */
429 static int db_err_callback(dev_info_t *dip, ddi_fm_error_t *derr,
430 const void *impl_data);
431
432 /*
433 * init/fini routines to alloc/dealloc fm structures and
434 * register/unregister our callback.
435 */
436 static void db_fm_init(db_ctrl_t *db_p);
437 static void db_fm_fini(db_ctrl_t *db_p);
438
439 int
_init(void)440 _init(void)
441 {
442 int rc;
443
444 DB_DEBUG0(DB_INIT|DB_DONT_DISPLAY_DIP, NULL, "enter\n");
445 if (((rc = ddi_soft_state_init(&db_state,
446 sizeof (db_ctrl_t), 1)) == 0) &&
447 ((rc = mod_install(&modlinkage)) != 0))
448 ddi_soft_state_fini(&db_state);
449 DB_DEBUG1(DB_INIT|DB_DONT_DISPLAY_DIP, NULL, "exit rc=%d\n", rc);
450 return (rc);
451 }
452
453
454 int
_fini(void)455 _fini(void)
456 {
457 int rc;
458
459 DB_DEBUG0(DB_FINI|DB_DONT_DISPLAY_DIP, NULL, "enter\n");
460 if ((rc = mod_remove(&modlinkage)) == 0)
461 ddi_soft_state_fini(&db_state);
462 DB_DEBUG1(DB_FINI|DB_DONT_DISPLAY_DIP, NULL, "exit rc=%d\n", rc);
463 return (rc);
464 }
465
466 int
_info(struct modinfo * modinfop)467 _info(struct modinfo *modinfop)
468 {
469 int rc;
470 rc = mod_info(&modlinkage, modinfop);
471 DB_DEBUG1(DB_INFO|DB_DONT_DISPLAY_DIP, NULL, "exit rc=%d\n", rc);
472 return (rc);
473 }
474
475 /*ARGSUSED*/
476 static int
db_getinfo(dev_info_t * dip,ddi_info_cmd_t infocmd,void * arg,void ** result)477 db_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
478 {
479 db_ctrl_t *dbp;
480 int rc = DDI_FAILURE;
481 minor_t minor = getminor((dev_t)arg);
482 int instance = PCIHP_AP_MINOR_NUM_TO_INSTANCE(minor);
483
484 DB_DEBUG1(DB_GETINFO|DB_DONT_DISPLAY_DIP, dip, "enter:cmd=%d\n",
485 infocmd);
486
487 switch (infocmd) {
488 case DDI_INFO_DEVT2DEVINFO:
489
490 if ((dbp = ddi_get_soft_state(db_state,
491 instance)) != NULL) {
492 *result = dbp->dip;
493 rc = DDI_SUCCESS;
494 } else
495 *result = NULL;
496 break;
497
498 case DDI_INFO_DEVT2INSTANCE:
499 *result = (void *)(uintptr_t)instance;
500 rc = DDI_SUCCESS;
501 break;
502
503 default:
504 break;
505 }
506 DB_DEBUG2(DB_GETINFO|DB_DONT_DISPLAY_DIP, dip,
507 "exit: result=%x, rc=%d\n", *result, rc);
508
509 return (rc);
510 }
511
512 static int
db_attach(dev_info_t * dip,ddi_attach_cmd_t cmd)513 db_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
514 {
515 int instance = ddi_get_instance(dip);
516 db_ctrl_t *dbp;
517 int rc = DDI_SUCCESS;
518 ddi_device_acc_attr_t db_csr_attr = { /* CSR map attributes */
519 DDI_DEVICE_ATTR_V0,
520 DDI_STRUCTURE_LE_ACC,
521 DDI_STRICTORDER_ACC
522 };
523 off_t bar_size;
524 int range_size;
525 char name[32];
526
527 DB_DEBUG1(DB_ATTACH, dip, "enter: cmd=%d\n", cmd);
528 switch (cmd) {
529
530 case DDI_ATTACH:
531 if (ddi_soft_state_zalloc(db_state, instance) != DDI_SUCCESS) {
532 rc = DDI_FAILURE;
533 break;
534 }
535
536 dbp = (db_ctrl_t *)ddi_get_soft_state(db_state, instance);
537
538 dbp->dip = dip;
539 mutex_init(&dbp->db_mutex, NULL, MUTEX_DRIVER, NULL);
540 dbp->db_soft_state = DB_SOFT_STATE_CLOSED;
541
542 /*
543 * Cannot use pci_config_setup here as we'd need
544 * to get a pointer to the address map to be able
545 * to set the bus private handle during child map
546 * operation.
547 */
548 if ((rc = ddi_regs_map_setup(dip, DB_PCI_CONF_RNUMBER,
549 (caddr_t *)&dbp->conf_io, DB_PCI_CONF_OFFSET,
550 PCI_CONF_HDR_SIZE, &db_csr_attr, &dbp->conf_handle))
551 != DDI_SUCCESS) {
552
553 cmn_err(CE_WARN,
554 "%s#%d: cannot map configuration space",
555 ddi_driver_name(dip), ddi_get_instance(dip));
556 mutex_destroy(&dbp->db_mutex);
557 ddi_soft_state_free(db_state, instance);
558 rc = DDI_FAILURE;
559 break;
560 }
561
562 db_get_perf_parameters(dbp);
563
564 if (ddi_dev_regsize(dip, DB_CSR_MEMBAR_RNUMBER, &bar_size)
565 != DDI_SUCCESS) {
566 cmn_err(CE_WARN, "%s#%d: cannot get memory CSR size",
567 ddi_driver_name(dbp->dip),
568 ddi_get_instance(dbp->dip));
569 ddi_regs_map_free(&dbp->conf_handle);
570 mutex_destroy(&dbp->db_mutex);
571 ddi_soft_state_free(db_state, instance);
572 rc = DDI_FAILURE;
573 break;
574 }
575
576 /* map memory CSR space */
577 if (ddi_regs_map_setup(dip, DB_CSR_MEMBAR_RNUMBER,
578 (caddr_t *)&dbp->csr_mem, DB_CSR_MEM_OFFSET, bar_size,
579 &db_csr_attr, &dbp->csr_mem_handle) != DDI_SUCCESS) {
580
581 cmn_err(CE_WARN, "%s#%d: cannot map memory CSR space",
582 ddi_driver_name(dbp->dip),
583 ddi_get_instance(dbp->dip));
584 ddi_regs_map_free(&dbp->conf_handle);
585 mutex_destroy(&dbp->db_mutex);
586 ddi_soft_state_free(db_state, instance);
587 rc = DDI_FAILURE;
588 break;
589 }
590
591 if (ddi_dev_regsize(dip, DB_CSR_IOBAR_RNUMBER, &bar_size)
592 != DDI_SUCCESS) {
593 cmn_err(CE_WARN, "%s#%d: cannot get IO CSR size",
594 ddi_driver_name(dbp->dip),
595 ddi_get_instance(dbp->dip));
596 ddi_regs_map_free(&dbp->csr_mem_handle);
597 ddi_regs_map_free(&dbp->conf_handle);
598 mutex_destroy(&dbp->db_mutex);
599 ddi_soft_state_free(db_state, instance);
600 rc = DDI_FAILURE;
601 break;
602 }
603
604 /*
605 * map IO CSR space. We need this map to initiate
606 * indirect configuration transactions as this is a better
607 * option than doing through configuration space map.
608 */
609 if (ddi_regs_map_setup(dip, DB_CSR_IOBAR_RNUMBER,
610 (caddr_t *)&dbp->csr_io, DB_CSR_IO_OFFSET, bar_size,
611 &db_csr_attr, &dbp->csr_io_handle) != DDI_SUCCESS) {
612
613 cmn_err(CE_WARN, "%s#%d: cannot map IO CSR space",
614 ddi_driver_name(dbp->dip),
615 ddi_get_instance(dbp->dip));
616 ddi_regs_map_free(&dbp->csr_mem_handle);
617 ddi_regs_map_free(&dbp->conf_handle);
618 mutex_destroy(&dbp->db_mutex);
619 ddi_soft_state_free(db_state, instance);
620 rc = DDI_FAILURE;
621 break;
622 }
623
624 db_orientation(dbp);
625
626 if (dbp->dev_state & DB_SECONDARY_NEXUS) {
627 if (pcihp_init(dip) != DDI_SUCCESS)
628 cmn_err(CE_WARN,
629 "%s#%d: could not register with hotplug",
630 ddi_driver_name(dbp->dip),
631 ddi_get_instance(dbp->dip));
632 } else {
633 /*
634 * create minor node for devctl interfaces
635 */
636 if (ddi_create_minor_node(dip, "devctl", S_IFCHR,
637 PCIHP_AP_MINOR_NUM(instance, PCIHP_DEVCTL_MINOR),
638 DDI_NT_NEXUS, 0) != DDI_SUCCESS) {
639 ddi_regs_map_free(&dbp->csr_io_handle);
640 ddi_regs_map_free(&dbp->csr_mem_handle);
641 ddi_regs_map_free(&dbp->conf_handle);
642 mutex_destroy(&dbp->db_mutex);
643 ddi_soft_state_free(db_state, instance);
644 rc = DDI_FAILURE;
645 break;
646 }
647 }
648
649 db_enable_io(dbp);
650
651 range_size = sizeof (dbp->range);
652 if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip,
653 DDI_PROP_DONTPASS, "bus-range", (caddr_t)&dbp->range,
654 &range_size) != DDI_SUCCESS) {
655
656 cmn_err(CE_WARN,
657 "%s#%d: cannot get bus-range property",
658 ddi_driver_name(dip), ddi_get_instance(dip));
659
660 if (dbp->dev_state & DB_SECONDARY_NEXUS)
661 (void) pcihp_uninit(dip);
662 else
663 ddi_remove_minor_node(dip, "devctl");
664
665 ddi_regs_map_free(&dbp->csr_mem_handle);
666 ddi_regs_map_free(&dbp->csr_io_handle);
667 ddi_regs_map_free(&dbp->conf_handle);
668 mutex_destroy(&dbp->db_mutex);
669 ddi_soft_state_free(db_state, instance);
670 rc = DDI_FAILURE;
671 break;
672 }
673
674 (void) sprintf(name, "%d", instance);
675
676 if (ddi_create_minor_node(dip, name, S_IFCHR,
677 PCIHP_AP_MINOR_NUM(instance, PCIHP_DEBUG_MINOR),
678 NULL, NULL) == DDI_FAILURE) {
679 cmn_err(CE_NOTE, "%s#%d: node creation failure",
680 ddi_driver_name(dbp->dip), instance);
681 }
682
683 mutex_init(&dbp->db_busown, NULL, MUTEX_DRIVER, NULL);
684
685 db_fm_init(dbp);
686 ddi_report_dev(dip);
687 dbp->dev_state |= DB_ATTACHED;
688
689 break;
690
691 case DDI_RESUME:
692
693 /*
694 * Get the soft state structure for the bridge.
695 */
696 dbp = (db_ctrl_t *)ddi_get_soft_state(db_state, instance);
697 db_enable_io(dbp);
698 (void) db_restore_config_regs(dbp);
699 dbp->dev_state &= ~DB_SUSPENDED;
700 break;
701
702 default:
703 rc = DDI_FAILURE; /* not supported yet */
704 break;
705 }
706
707 DB_DEBUG1(DB_ATTACH, dip, "exit: rc=%d\n", rc);
708 return (rc);
709 }
710
711 static int
db_detach(dev_info_t * dip,ddi_detach_cmd_t cmd)712 db_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
713 {
714 int instance = ddi_get_instance(dip);
715 db_ctrl_t *dbp;
716 int rc = DDI_SUCCESS;
717 char name[32];
718
719 dbp = (db_ctrl_t *)ddi_get_soft_state(db_state, instance);
720
721 DB_DEBUG1(DB_DETACH, dip, "enter: cmd=%d\n", cmd);
722
723 switch (cmd) {
724
725 case DDI_DETACH :
726 db_fm_fini(dbp);
727 if (dbp->dev_state & DB_SECONDARY_NEXUS)
728 if (pcihp_uninit(dip) == DDI_FAILURE)
729 return (DDI_FAILURE);
730 else
731 ddi_remove_minor_node(dip, "devctl");
732
733 mutex_destroy(&dbp->db_busown);
734 ddi_regs_map_free(&dbp->csr_mem_handle);
735 ddi_regs_map_free(&dbp->csr_io_handle);
736
737 ddi_regs_map_free(&dbp->conf_handle);
738 dbp->dev_state &= ~DB_ATTACHED;
739 (void) sprintf(name, "%d", instance);
740 ddi_remove_minor_node(dip, name);
741 mutex_destroy(&dbp->db_mutex);
742 ddi_soft_state_free(db_state, instance);
743 break;
744
745 case DDI_SUSPEND :
746 if (db_save_config_regs(dbp) != DDI_SUCCESS) {
747 cmn_err(CE_WARN,
748 "%s#%d: Ignoring Child state Suspend Error",
749 ddi_driver_name(dbp->dip),
750 ddi_get_instance(dbp->dip));
751 }
752 dbp->dev_state |= DB_SUSPENDED;
753 break;
754
755 default :
756 rc = DDI_FAILURE;
757 break;
758 }
759
760 DB_DEBUG1(DB_DETACH, dip, "exit: rc=%d\n", rc);
761 return (rc);
762 }
763
764 static void
db_get_perf_parameters(db_ctrl_t * dbp)765 db_get_perf_parameters(db_ctrl_t *dbp)
766 {
767 dbp->p_latency_timer = (int8_t)ddi_prop_get_int(DDI_DEV_T_ANY,
768 dbp->dip, 0, "p-latency-timer", p_latency_timer);
769 dbp->s_latency_timer = (int8_t)ddi_prop_get_int(DDI_DEV_T_ANY,
770 dbp->dip, 0, "s-latency-timer", s_latency_timer);
771 dbp->p_cache_line_size = (int8_t)ddi_prop_get_int(DDI_DEV_T_ANY,
772 dbp->dip, 0, "p-cache-line-size", p_cache_line_size);
773 dbp->s_cache_line_size = (int8_t)ddi_prop_get_int(DDI_DEV_T_ANY,
774 dbp->dip, 0, "s-cache-line-size", s_cache_line_size);
775 dbp->p_pwrite_threshold = (int8_t)ddi_prop_get_int(DDI_DEV_T_ANY,
776 dbp->dip, 0, "p-pwrite-threshold", p_pwrite_threshold);
777 dbp->s_pwrite_threshold = (int8_t)ddi_prop_get_int(DDI_DEV_T_ANY,
778 dbp->dip, 0, "s-pwrite-threshold", s_pwrite_threshold);
779 dbp->p_dread_threshold = (int8_t)ddi_prop_get_int(DDI_DEV_T_ANY,
780 dbp->dip, 0, "p-dread-threshold", p_dread_threshold);
781 dbp->s_dread_threshold = (int8_t)ddi_prop_get_int(DDI_DEV_T_ANY,
782 dbp->dip, 0, "s-dread-threshold", s_dread_threshold);
783 dbp->delayed_trans_order = (int8_t)ddi_prop_get_int(DDI_DEV_T_ANY,
784 dbp->dip, 0, "delayed-trans-order", delayed_trans_order);
785 }
786
787 static void
db_set_perf_parameters(db_ctrl_t * dbp)788 db_set_perf_parameters(db_ctrl_t *dbp)
789 {
790 uint_t poffset = 0, soffset = 0;
791
792 if (dbp->dev_state & DB_SECONDARY_NEXUS)
793 poffset = DB_SCONF_PRI_HDR_OFF;
794 else
795 soffset = DB_PCONF_SEC_HDR_OFF;
796
797 if ((dbp->p_latency_timer != (int8_t)DEF_INVALID_REG_VAL) &&
798 (dbp->p_latency_timer != -1))
799 ddi_put8(dbp->conf_handle,
800 (uint8_t *)dbp->conf_io+poffset+PCI_CONF_LATENCY_TIMER,
801 dbp->p_latency_timer);
802 if ((dbp->s_latency_timer != (int8_t)DEF_INVALID_REG_VAL) &&
803 (dbp->s_latency_timer != -1))
804 ddi_put8(dbp->conf_handle,
805 (uint8_t *)dbp->conf_io+soffset+PCI_CONF_LATENCY_TIMER,
806 dbp->s_latency_timer);
807 if ((dbp->p_cache_line_size != (int8_t)DEF_INVALID_REG_VAL) &&
808 (dbp->p_cache_line_size != -1))
809 ddi_put8(dbp->conf_handle,
810 (uint8_t *)dbp->conf_io+poffset+PCI_CONF_CACHE_LINESZ,
811 dbp->p_cache_line_size);
812 if ((dbp->s_cache_line_size != (int8_t)DEF_INVALID_REG_VAL) &&
813 (dbp->s_cache_line_size != -1))
814 ddi_put8(dbp->conf_handle,
815 (uint8_t *)dbp->conf_io+soffset+PCI_CONF_CACHE_LINESZ,
816 dbp->s_cache_line_size);
817 if ((dbp->p_pwrite_threshold != (int8_t)DEF_INVALID_REG_VAL) &&
818 (dbp->p_pwrite_threshold != -1))
819 ddi_put16(dbp->conf_handle, (uint16_t *)
820 ((uchar_t *)dbp->conf_io+DB_CONF_CHIP_CTRL1),
821 (ddi_get16(dbp->conf_handle, (uint16_t *)
822 ((uchar_t *)dbp->conf_io+DB_CONF_CHIP_CTRL1)) &
823 ~P_PW_THRESHOLD) |
824 (dbp->p_pwrite_threshold?P_PW_THRESHOLD:0));
825 if ((dbp->s_pwrite_threshold != (int8_t)DEF_INVALID_REG_VAL) &&
826 (dbp->s_pwrite_threshold != -1))
827 ddi_put16(dbp->conf_handle, (uint16_t *)
828 ((uchar_t *)dbp->conf_io+DB_CONF_CHIP_CTRL1),
829 (ddi_get16(dbp->conf_handle, (uint16_t *)
830 ((uchar_t *)dbp->conf_io+DB_CONF_CHIP_CTRL1)) &
831 ~S_PW_THRESHOLD) |
832 (dbp->s_pwrite_threshold?S_PW_THRESHOLD:0));
833 /* primary delayed read threshold. 0x01 is reserved ?. */
834 if ((dbp->p_dread_threshold != (int8_t)DEF_INVALID_REG_VAL) &&
835 (dbp->p_dread_threshold != -1))
836 ddi_put16(dbp->conf_handle, (uint16_t *)
837 ((uchar_t *)dbp->conf_io+DB_CONF_CHIP_CTRL1),
838 ((ddi_get16(dbp->conf_handle, (uint16_t *)
839 ((uchar_t *)dbp->conf_io+DB_CONF_CHIP_CTRL1)) &
840 ~P_DREAD_THRESHOLD_MASK) |
841 ((dbp->p_dread_threshold &
842 DREAD_THRESHOLD_VALBITS)<<2)));
843 /* secondary delayed read threshold. 0x01 is reserved ?. */
844 if ((dbp->s_dread_threshold != (int8_t)DEF_INVALID_REG_VAL) &&
845 (dbp->s_dread_threshold != -1))
846 ddi_put16(dbp->conf_handle, (uint16_t *)
847 ((uchar_t *)dbp->conf_io+DB_CONF_CHIP_CTRL1),
848 ((ddi_get16(dbp->conf_handle, (uint16_t *)
849 ((uchar_t *)dbp->conf_io+DB_CONF_CHIP_CTRL1)) &
850 ~S_DREAD_THRESHOLD_MASK) |
851 ((dbp->s_dread_threshold &
852 DREAD_THRESHOLD_VALBITS)<<4)));
853 if ((dbp->delayed_trans_order != (int8_t)DEF_INVALID_REG_VAL) &&
854 (dbp->delayed_trans_order != -1))
855 ddi_put16(dbp->conf_handle, (uint16_t *)
856 ((uchar_t *)dbp->conf_io+DB_CONF_CHIP_CTRL0),
857 (ddi_get16(dbp->conf_handle, (uint16_t *)
858 ((uchar_t *)dbp->conf_io+DB_CONF_CHIP_CTRL0)) &
859 ~DELAYED_TRANS_ORDER) |
860 (dbp->delayed_trans_order?DELAYED_TRANS_ORDER:0));
861 }
862
863 static void
db_orientation(db_ctrl_t * dbp)864 db_orientation(db_ctrl_t *dbp)
865 {
866 dev_info_t *dip = dbp->dip;
867 uint8_t pif;
868 uint32_t mem1;
869 uint32_t newval;
870
871 /*
872 * determine orientation of drawbridge and enable
873 * Upstream or Downstream path.
874 */
875
876 /*
877 * if PIF is set correctly, use it to determine orientation
878 */
879 pif = ddi_get8(dbp->conf_handle, (uchar_t *)dbp->conf_io +
880 PCI_CONF_PROGCLASS);
881 if (pif & 0xff) {
882 if (pif & DB_PIF_SECONDARY_TO_HOST) {
883 dbp->dev_state = DB_SECONDARY_NEXUS;
884 DB_DEBUG0(DB_ATTACH, dip,
885 "db_orientation: pif secondary\n");
886 return;
887 }
888 if (pif & DB_PIF_PRIMARY_TO_HOST) {
889 dbp->dev_state = DB_PRIMARY_NEXUS;
890 DB_DEBUG0(DB_ATTACH, dip,
891 "db_orientation: pif primary\n");
892 return;
893 }
894 /* otherwise, fall through */
895 }
896
897 /*
898 * otherwise, test the chip directly by trying to write
899 * downstream mem1 setup register, only writeable from
900 * secondary.
901 */
902 mem1 = ddi_get32(dbp->conf_handle,
903 (uint32_t *)((uchar_t *)dbp->conf_io +
904 DB_CONF_DS_IO_MEM1_SETUP));
905
906 ddi_put32(dbp->conf_handle,
907 (uint32_t *)((uchar_t *)(dbp->conf_io +
908 DB_CONF_DS_IO_MEM1_SETUP)), ~mem1);
909
910 newval = ddi_get32(dbp->conf_handle,
911 (uint32_t *)((uchar_t *)dbp->conf_io +
912 DB_CONF_DS_IO_MEM1_SETUP));
913
914 if (newval == mem1)
915 /* we couldn't write it, orientation is primary */
916 dbp->dev_state = DB_PRIMARY_NEXUS;
917 else {
918 /*
919 * we could write it, therefore orientation secondary.
920 * restore mem1 value.
921 */
922 dbp->dev_state = DB_SECONDARY_NEXUS;
923 ddi_put32(dbp->conf_handle,
924 (uint32_t *)((uchar_t *)(dbp->conf_io +
925 DB_CONF_DS_IO_MEM1_SETUP)), mem1);
926 }
927
928
929 if (dbp->dev_state & DB_PRIMARY_NEXUS) {
930 DB_DEBUG0(DB_ATTACH, dip, "db_orientation: chip primary\n");
931 } else {
932 DB_DEBUG0(DB_ATTACH, dip, "db_orientation: chip secondary\n");
933 }
934 }
935
936 static void
db_enable_io(db_ctrl_t * dbp)937 db_enable_io(db_ctrl_t *dbp)
938 {
939 dev_info_t *dip = dbp->dip;
940 pci_regspec_t *reg;
941 int rcount, length, i;
942 uint32_t offset;
943 uint32_t p_offset, s_offset;
944 uint16_t regval;
945 uint16_t enable;
946
947 /*
948 * Step 0:
949 * setup the primary and secondary offset and enable
950 * values based on the orientation of 21554.
951 */
952 if (dbp->dev_state & DB_PRIMARY_NEXUS) {
953 DB_DEBUG0(DB_ATTACH, dip, "db_enable_io: primary\n");
954 p_offset = 0;
955 s_offset = DB_SCONF_HDR_OFF;
956 enable = DS_ENABLE;
957 } else {
958 DB_DEBUG0(DB_ATTACH, dip, "db_enable_io: secondary\n");
959 p_offset = DB_SCONF_HDR_OFF;
960 s_offset = 0;
961 enable = US_ENABLE;
962 }
963
964 db_set_perf_parameters(dbp);
965 db_set_dvma_range(dbp);
966
967 /*
968 * Step 1:
969 * setup latency timer and cache line size parameters
970 * which are used for child initialization.
971 */
972 dbp->latency_timer = ddi_get8(dbp->conf_handle, (uint8_t *)
973 ((caddr_t)dbp->conf_io+PCI_CONF_LATENCY_TIMER));
974
975 dbp->cache_line_size = ddi_get8(dbp->conf_handle, (uint8_t *)
976 ((caddr_t)dbp->conf_io+PCI_CONF_CACHE_LINESZ));
977
978 DB_DEBUG2(DB_ATTACH, dip,
979 "db_enable_io: latency %d, cache line size %d\n",
980 dbp->latency_timer, dbp->cache_line_size);
981
982 /*
983 * Step 2: program command reg on both primary and secondary
984 * interfaces.
985 */
986 ddi_put16(dbp->conf_handle, (uint16_t *)((caddr_t)dbp->conf_io +
987 (off_t)(p_offset + PCI_CONF_COMM)), db_command_default);
988
989 ddi_put16(dbp->conf_handle, (uint16_t *)((caddr_t)dbp->conf_io +
990 (off_t)(s_offset + PCI_CONF_COMM)), db_command_default);
991
992 /*
993 * Step 3:
994 * set up translated base registers, using the primary/
995 * secondary interface pci configuration Base Address
996 * Registers (BAR's).
997 */
998
999 /* mem0 translated base is setup for primary orientation only. */
1000 if (dbp->dev_state & DB_PRIMARY_NEXUS) {
1001 /*
1002 * And only if the 21554 device node property indicates
1003 * the size of base0 register to be larger than csr map
1004 * space, DB_CSR_SIZE=4K.
1005 *
1006 * Note : Setting up 1:1 translations only (for now:), i.e.
1007 * no look up table.
1008 */
1009 if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
1010 DDI_PROP_DONTPASS, "reg", (caddr_t)®,
1011 &length) != DDI_PROP_SUCCESS) {
1012 DB_DEBUG0(DB_ATTACH, dip,
1013 "Failed to read reg property\n");
1014 return;
1015 }
1016
1017 /* Find device node's base0 reg property and check its size */
1018 rcount = length / sizeof (pci_regspec_t);
1019 for (i = 0; i < rcount; i++) {
1020 offset = PCI_REG_REG_G(reg[i].pci_phys_hi);
1021 if ((offset == PCI_CONF_BASE0) &&
1022 (reg[i].pci_size_low > DB_CSR_SIZE))
1023 break;
1024 }
1025
1026 /*
1027 * set up mem0 translated base, if base0 register was
1028 * found and its size was larger than csr map space.
1029 */
1030 if (i != rcount) {
1031 DB_DEBUG0(DB_ATTACH, dip,
1032 "db_enable_io: setting up MEM0_TR_BASE\n");
1033 DB_DEBUG1(DB_ATTACH, dip, "BASE0 register = %x\n",
1034 pci_config_get32(dbp->conf_handle,
1035 (off_t)(p_offset + PCI_CONF_BASE0)));
1036
1037 pci_config_put32(dbp->conf_handle,
1038 (off_t)DB_CONF_DS_MEM0_TR_BASE,
1039 pci_config_get32(dbp->conf_handle,
1040 (off_t)(p_offset + PCI_CONF_BASE0)));
1041
1042 DB_DEBUG1(DB_ATTACH, dip,
1043 "db_enable_io: MEM0_TR_BASE set value = %x\n",
1044 pci_config_get32(dbp->conf_handle,
1045 (off_t)DB_CONF_DS_MEM0_TR_BASE));
1046 }
1047 kmem_free(reg, length);
1048 }
1049
1050 pci_config_put32(dbp->conf_handle, (off_t)DB_CONF_DS_IO_MEM1_TR_BASE,
1051 ((pci_config_get32(dbp->conf_handle,
1052 (off_t)(p_offset + PCI_CONF_BASE2))) & ~DB_IO_BIT));
1053
1054 pci_config_put32(dbp->conf_handle, (off_t)DB_CONF_DS_MEM2_TR_BASE,
1055 ((pci_config_get32(dbp->conf_handle,
1056 (off_t)(p_offset + PCI_CONF_BASE3))) & ~DB_IO_BIT));
1057
1058 pci_config_put32(dbp->conf_handle, (off_t)DB_CONF_DS_MEM3_TR_BASE,
1059 ((pci_config_get32(dbp->conf_handle,
1060 (off_t)(p_offset + PCI_CONF_BASE4))) & ~DB_IO_BIT));
1061
1062 pci_config_put32(dbp->conf_handle, (off_t)DB_CONF_US_IO_MEM0_TR_BASE,
1063 ((pci_config_get32(dbp->conf_handle,
1064 (off_t)(s_offset + PCI_CONF_BASE2))) & ~DB_IO_BIT));
1065
1066 pci_config_put32(dbp->conf_handle, (off_t)DB_CONF_US_MEM1_TR_BASE,
1067 ((pci_config_get32(dbp->conf_handle,
1068 (off_t)(s_offset + PCI_CONF_BASE3))) & ~DB_IO_BIT));
1069
1070 /*
1071 * Step 4: enable downstream (for primary orientation) or upstream
1072 * (for secondary orientation) bits in Configuration Control
1073 * and Status register, if not already enabled.
1074 */
1075 regval = pci_config_get16(dbp->conf_handle, (off_t)DB_CONF_CONF_CSR);
1076
1077 DB_DEBUG1(DB_ATTACH, dip, "db_enable_io: CSR value before: %x\n",
1078 regval);
1079
1080 if (!(regval & enable)) {
1081 /* enable down/upstream configuration transactions */
1082 regval |= enable;
1083 pci_config_put16(dbp->conf_handle, (off_t)DB_CONF_CONF_CSR,
1084 regval);
1085 regval = pci_config_get16(dbp->conf_handle,
1086 (off_t)DB_CONF_CONF_CSR);
1087 }
1088 DB_DEBUG1(DB_ATTACH, dip, "db_enable_io: CSR value after: %x\n",
1089 regval);
1090
1091 /*
1092 * Step 5: enable downstream/upstream I/O (through CSR space)
1093 */
1094 regval = ddi_get16(dbp->csr_mem_handle,
1095 (uint16_t *)((uchar_t *)dbp->csr_mem + DB_CSR_IO_CSR));
1096
1097 DB_DEBUG1(DB_ATTACH, dip, "db_enable_io: IO_CSR value before: %x\n",
1098 regval);
1099 if (!(regval & enable)) {
1100 regval |= enable;
1101 ddi_put16(dbp->csr_mem_handle,
1102 (uint16_t *)((uchar_t *)dbp->csr_mem +
1103 DB_CSR_IO_CSR), regval);
1104
1105 regval = ddi_get16(dbp->csr_mem_handle,
1106 (uint16_t *)((uchar_t *)dbp->csr_mem + DB_CSR_IO_CSR));
1107 }
1108 DB_DEBUG1(DB_ATTACH, dip, "db_enable_io: IO_CSR value after: %x\n",
1109 regval);
1110
1111 /*
1112 * Step 6: if 21554 orientation is primary to host,
1113 * forward SERR# to host.
1114 */
1115 if (dbp->dev_state & DB_PRIMARY_NEXUS) {
1116 dbp->serr_fwd_enable = ddi_prop_get_int(DDI_DEV_T_ANY,
1117 dbp->dip, 0, "serr-fwd-enable", db_serr_fwd_enable);
1118
1119 regval = ddi_get16(dbp->conf_handle,
1120 (uint16_t *)((uchar_t *)dbp->conf_io +
1121 DB_CONF_CHIP_CTRL0));
1122
1123 DB_DEBUG1(DB_ATTACH, dip,
1124 "db_enable_io: CHIP_CTRL0 value before: %x\n", regval);
1125
1126 ddi_put16(dbp->conf_handle,
1127 (uint16_t *)((uchar_t *)dbp->conf_io +
1128 DB_CONF_CHIP_CTRL0),
1129 (regval & ~SERR_FWD) |
1130 (dbp->serr_fwd_enable?SERR_FWD:0));
1131
1132 regval = ddi_get16(dbp->conf_handle,
1133 (uint16_t *)((uchar_t *)dbp->conf_io +
1134 DB_CONF_CHIP_CTRL0));
1135
1136 DB_DEBUG1(DB_ATTACH, dip,
1137 "db_enable_io: CHIP_CTRL0 value after: %x\n", regval);
1138 }
1139
1140 /*
1141 * Step 7: if orientation is secondary, make sure primary lockout
1142 * disable is reset.
1143 */
1144
1145 if (dbp->dev_state & DB_SECONDARY_NEXUS) {
1146 regval = pci_config_get16(dbp->conf_handle,
1147 (off_t)DB_CONF_CHIP_CTRL0);
1148 DB_DEBUG1(DB_ATTACH, dip,
1149 "db_enable_io: chip ctrl (0x%x) before\n", regval);
1150 if (regval & PLOCKOUT)
1151 pci_config_put16(dbp->conf_handle,
1152 (off_t)DB_CONF_CHIP_CTRL0,
1153 (regval & ~PLOCKOUT));
1154 regval = pci_config_get16(dbp->conf_handle,
1155 (off_t)DB_CONF_CHIP_CTRL0);
1156 DB_DEBUG1(DB_ATTACH, dip,
1157 "db_enable_io: chip ctrl (0x%x) after\n", regval);
1158 }
1159 }
1160
1161 /*
1162 * Set DVMA Address Range.
1163 * This code is common to both orientations of the nexus driver.
1164 */
1165 static void
db_set_dvma_range(db_ctrl_t * dbp)1166 db_set_dvma_range(db_ctrl_t *dbp)
1167 {
1168 uint32_t dvma_start = 0;
1169 uint32_t dvma_len = 0;
1170 uint64_t db_allocd = 0;
1171 uint32_t *dvma_prop;
1172 uint32_t dvma_size[2]; /* dvma size may span over 2 BARs */
1173 uint32_t dvma_bar[2]; /* dvma range may span over 2 BARs */
1174 int dvma_prop_len;
1175 uint64_t new_dvma_start, new_dvma_len, new_dvma_end;
1176
1177 /*
1178 * Need to traverse up the tree looking for a
1179 * "virtual-dma" property that specifies the
1180 * HPB DVMA range.
1181 */
1182 if (ddi_getlongprop(DDI_DEV_T_ANY, ddi_get_parent(dbp->dip), 0,
1183 "virtual-dma", (caddr_t)&dvma_prop, &dvma_prop_len)
1184 == DDI_SUCCESS) {
1185 dvma_start = dvma_prop[0];
1186 dvma_len = dvma_prop[1];
1187 kmem_free((caddr_t)dvma_prop, dvma_prop_len);
1188 } else {
1189 /*
1190 * For initial implementation, lets avoid a warning since this
1191 * change has not been implemented in the host-pci nexus
1192 * driver.
1193 */
1194 cmn_err(CE_WARN,
1195 "%s#%d: Could not get \"virtual-dma\" property",
1196 ddi_driver_name(dbp->dip),
1197 ddi_get_instance(dbp->dip));
1198 dvma_start = db_dvma_start;
1199 dvma_len = db_dvma_len;
1200 }
1201
1202 DB_DEBUG2(DB_DVMA, dbp->dip,
1203 "DVMA Range is %lx,%lx\n", dvma_start, dvma_len);
1204
1205 dvma_size[0] = dvma_size[1] = 0;
1206 /* Validate DVMA size programming and system requirements. */
1207 if (dbp->dev_state & DB_SECONDARY_NEXUS) {
1208 dvma_size[0] = pci_config_get32(dbp->conf_handle,
1209 DB_CONF_DS_IO_MEM1_SETUP);
1210 if (!(dvma_size[0] & 1)) /* make sure it is not a IO BAR */
1211 dvma_size[0] = ((~dvma_size[0]) + 1) & 0xfffff000;
1212 else
1213 dvma_size[0] = 0;
1214 dvma_size[1] = db_dvma_len;
1215 } else {
1216 dvma_size[0] = pci_config_get32(dbp->conf_handle,
1217 DB_CONF_US_IO_MEM0_SETUP);
1218 if (!(dvma_size[0] & 1)) /* make sure it is not a IO BAR */
1219 dvma_size[0] = ((~dvma_size[0]) + 1) & 0xfffff000;
1220 else
1221 dvma_size[0] = 0;
1222 dvma_size[1] = ((~(pci_config_get32(dbp->conf_handle,
1223 DB_CONF_US_MEM1_SETUP))) + 1) & 0xfffff000;
1224 }
1225 DB_DEBUG2(DB_DVMA, dbp->dip, "DVMA size register pair %lx, %lx\n",
1226 dvma_size[0], dvma_size[1]);
1227
1228 #ifdef DEBUG
1229 if ((dvma_size[0] + dvma_size[1]) < dvma_len)
1230 cmn_err(CE_WARN, "%s#%d: DVMA window (%u) does not coincide"
1231 " with system requirements",
1232 ddi_driver_name(dbp->dip), ddi_get_instance(dbp->dip),
1233 (dvma_size[0] + dvma_size[1]));
1234 #endif
1235 dvma_bar[0] = dvma_bar[1] = 0xFFFFFFFF;
1236 db_allocd = 0;
1237 new_dvma_start = dvma_start;
1238 new_dvma_len = dvma_len;
1239
1240 /* now, program the correct DVMA range over the 2 BARs. Max 4GB */
1241 if (dvma_size[0]) {
1242 dvma_bar[0] = (uint32_t)(dvma_start & (~(dvma_size[0] - 1)));
1243 new_dvma_end = (uint64_t)((uint64_t)dvma_bar[0] +
1244 (uint64_t)dvma_size[0]);
1245 if (new_dvma_end > (new_dvma_start + new_dvma_len))
1246 new_dvma_end = new_dvma_start + new_dvma_len;
1247 db_allocd += (new_dvma_end - new_dvma_start);
1248 new_dvma_start = new_dvma_end;
1249 new_dvma_len = dvma_len - db_allocd;
1250 }
1251 /*
1252 * It does not serve any purpose to set the other DVMA register
1253 * when we have already met the memory requirements so leave it
1254 * disabled.
1255 */
1256 if ((db_allocd != dvma_len) && dvma_size[1]) {
1257 dvma_bar[1] = (uint32_t)((dvma_start + db_allocd) &
1258 (~(dvma_size[1] - 1)));
1259 new_dvma_end = (uint64_t)((uint64_t)dvma_bar[1] +
1260 (uint64_t)dvma_size[1]);
1261 if (new_dvma_end > (new_dvma_start + new_dvma_len))
1262 new_dvma_end = new_dvma_start + new_dvma_len;
1263 db_allocd += (new_dvma_end - new_dvma_start);
1264 }
1265
1266 /* In case of secondary orientation, DVMA BAR0 is 0. */
1267 if (dbp->dev_state & DB_SECONDARY_NEXUS)
1268 dvma_bar[0] = 0;
1269
1270 if (db_allocd != dvma_len) {
1271 cmn_err(CE_WARN, "%s#%d: dvma range error!",
1272 ddi_driver_name(dbp->dip), ddi_get_instance(dbp->dip));
1273 }
1274
1275 DB_DEBUG2(DB_DVMA, dbp->dip, "DVMA BARs set as %x, %x\n",
1276 dvma_bar[0], dvma_bar[1]);
1277
1278 /* configure the setup register and DVMA BARs. */
1279 if (dbp->dev_state & DB_SECONDARY_NEXUS) {
1280 if (dvma_bar[0] != 0xFFFFFFFF) {
1281 #ifdef DB_SEC_SETUP_WRITE
1282 /*
1283 * No need to program the setup register
1284 * as the PROM would have done it.
1285 */
1286 pci_config_put32(dbp->conf_handle,
1287 DB_CONF_DS_MEM1_SETUP,
1288 (uint32_t)(((~(dvma_size[0] - 1)) |
1289 (pci_config_get32(dbp->conf_handle,
1290 DB_CONF_DS_MEM1_SETUP) & 0xF)) | 0x80000000));
1291 #endif
1292 /*
1293 * when translations are to be provided, this will
1294 * change.
1295 */
1296 pci_config_put32(dbp->conf_handle,
1297 DB_CONF_DS_IO_MEM1_TR_BASE,
1298 (uint32_t)dvma_bar[0]);
1299 pci_config_put32(dbp->conf_handle,
1300 DB_SCONF_DS_IO_MEM1, dvma_bar[0]);
1301 }
1302 if (dvma_bar[1] != 0xFFFFFFFF) {
1303 #ifdef DB_SEC_SETUP_WRITE
1304 /*
1305 * No need to program the setup register
1306 * as the PROM would have done it.
1307 */
1308 pci_config_put32(dbp->conf_handle,
1309 DB_CONF_DS_MEM2_SETUP,
1310 (uint32_t)(((~(dvma_size[1] - 1)) |
1311 (pci_config_get32(dbp->conf_handle,
1312 DB_CONF_DS_MEM2_SETUP) & 0xF)) | 0x80000000));
1313 #endif
1314 /*
1315 * when translations are to be provided, this will
1316 * change.
1317 */
1318 pci_config_put32(dbp->conf_handle,
1319 DB_CONF_DS_MEM2_TR_BASE, (uint32_t)dvma_bar[1]);
1320 pci_config_put32(dbp->conf_handle,
1321 DB_SCONF_DS_MEM2, dvma_bar[1]);
1322 }
1323
1324 } else {
1325 if (dvma_bar[0] != 0xFFFFFFFF) {
1326 #ifdef DB_CONF_P2S_WRITE_ENABLED /* primary to secondary write enabled */
1327 /*
1328 * We have a problem with this setup, because the
1329 * US_MEM1 setup register cannot be written from the
1330 * primary interface...!!! Hence in this configuration,
1331 * we cannot dynamically program the DVMA range!
1332 */
1333 pci_config_put32(dbp->conf_handle,
1334 DB_CONF_US_IO_MEM0_SETUP,
1335 (uint32_t)(((~(dvma_size[0] - 1)) |
1336 (pci_config_get32(dbp->conf_handle,
1337 DB_CONF_US_IO_MEM0_SETUP) & 0xF)) |
1338 0x80000000));
1339 #endif
1340 /*
1341 * when translations are to be provided, this will
1342 * change.
1343 */
1344 pci_config_put32(dbp->conf_handle,
1345 DB_CONF_US_IO_MEM0_TR_BASE,
1346 (uint32_t)dvma_bar[0]);
1347 pci_config_put32(dbp->conf_handle,
1348 DB_PCONF_US_IO_MEM0, dvma_bar[0]);
1349 }
1350 if (dvma_bar[1] != 0xFFFFFFFF) {
1351 #ifdef DB_CONF_P2S_WRITE_ENABLED /* primary to secondary write enabled */
1352 /*
1353 * We have a problem with this setup, because the
1354 * US_MEM1 setup register cannot be written from the
1355 * primary interface...!!! Hence in this configuration,
1356 * we cannot dynamically program the DVMA range!
1357 */
1358 pci_config_put32(dbp->conf_handle,
1359 DB_CONF_US_MEM1_SETUP,
1360 (uint32_t)(((~(dvma_size[1] - 1)) |
1361 (pci_config_get32(dbp->conf_handle,
1362 DB_CONF_US_MEM1_SETUP) & 0xF)) | 0x80000000));
1363 #endif
1364 /*
1365 * when translations are to be provided, this will
1366 * change.
1367 */
1368 pci_config_put32(dbp->conf_handle,
1369 DB_CONF_US_MEM1_TR_BASE, (uint32_t)dvma_bar[1]);
1370 pci_config_put32(dbp->conf_handle,
1371 DB_PCONF_US_MEM1, dvma_bar[1]);
1372 }
1373 }
1374 }
1375
1376 /*ARGSUSED*/
1377 static int
db_open(dev_t * dev_p,int flag,int otyp,cred_t * cred_p)1378 db_open(dev_t *dev_p, int flag, int otyp, cred_t *cred_p)
1379 {
1380 minor_t minor = getminor(*dev_p);
1381 int instance = PCIHP_AP_MINOR_NUM_TO_INSTANCE(minor);
1382 db_ctrl_t *dbp = (db_ctrl_t *)ddi_get_soft_state(db_state, instance);
1383
1384 if (dbp == (db_ctrl_t *)NULL)
1385 return (ENXIO);
1386
1387 /*
1388 * check for debug node
1389 */
1390 if ((minor & 0xff) == 0xfe)
1391 return (0);
1392
1393 if (dbp->dev_state & DB_SECONDARY_NEXUS)
1394 return ((pcihp_get_cb_ops())->cb_open(dev_p, flag,
1395 otyp, cred_p));
1396 /*
1397 * Handle the open by tracking the device state.
1398 */
1399 mutex_enter(&dbp->db_mutex);
1400 if (flag & FEXCL) {
1401 if (dbp->db_soft_state != DB_SOFT_STATE_CLOSED) {
1402 mutex_exit(&dbp->db_mutex);
1403 return (EBUSY);
1404 }
1405 dbp->db_soft_state = DB_SOFT_STATE_OPEN_EXCL;
1406 } else {
1407 if (dbp->db_soft_state == DB_SOFT_STATE_OPEN_EXCL) {
1408 mutex_exit(&dbp->db_mutex);
1409 return (EBUSY);
1410 }
1411 dbp->db_soft_state = DB_SOFT_STATE_OPEN;
1412 }
1413 mutex_exit(&dbp->db_mutex);
1414 return (0);
1415 }
1416
1417 /*ARGSUSED*/
1418 static int
db_close(dev_t dev,int flag,int otyp,cred_t * cred_p)1419 db_close(dev_t dev, int flag, int otyp, cred_t *cred_p)
1420 {
1421 minor_t minor = getminor(dev);
1422 int instance = PCIHP_AP_MINOR_NUM_TO_INSTANCE(minor);
1423 db_ctrl_t *dbp = (db_ctrl_t *)ddi_get_soft_state(db_state, instance);
1424
1425 if (dbp == (db_ctrl_t *)NULL)
1426 return (ENXIO);
1427
1428 /*
1429 * check for debug node
1430 */
1431 if ((minor & 0xff) == 0xfe)
1432 return (0);
1433
1434 if (dbp->dev_state & DB_SECONDARY_NEXUS)
1435 return ((pcihp_get_cb_ops())->cb_close(dev, flag,
1436 otyp, cred_p));
1437 mutex_enter(&dbp->db_mutex);
1438 dbp->db_soft_state = DB_SOFT_STATE_CLOSED;
1439 mutex_exit(&dbp->db_mutex);
1440 return (0);
1441 }
1442
1443 /*ARGSUSED*/
1444 static int
db_ioctl(dev_t dev,int cmd,intptr_t arg,int mode,cred_t * cred_p,int * rval_p)1445 db_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *cred_p,
1446 int *rval_p)
1447 {
1448 int rc = DDI_SUCCESS;
1449 #ifdef DB_DEBUG
1450 ddi_acc_handle_t config_handle;
1451 db_pci_data_t pci_data;
1452 dev_info_t *child_dip;
1453 #endif
1454 dev_info_t *self;
1455 minor_t minor = getminor(dev);
1456 int instance = PCIHP_AP_MINOR_NUM_TO_INSTANCE(minor);
1457 struct devctl_iocdata *dcp;
1458 uint_t bus_state;
1459 db_ctrl_t *dbp = (db_ctrl_t *)ddi_get_soft_state(db_state, instance);
1460
1461 #ifdef DB_DEBUG
1462 /*
1463 * try this first whether were SECONDARY_NEXUS or not
1464 */
1465 if (cmd == DB_PCI_READ_CONF_HEADER) {
1466 if (ddi_copyin((caddr_t)arg, (caddr_t)&pci_data,
1467 sizeof (db_pci_data_t), mode)) {
1468 rc = EFAULT;
1469 return (rc);
1470 }
1471
1472 if (strcmp(pci_data.name, "") == 0) {
1473 child_dip = dbp->dip;
1474 (void) strcpy(pci_data.name,
1475 ddi_get_name(dbp->dip));
1476 } else {
1477
1478 if ((child_dip = db_lookup_child_name(dbp,
1479 pci_data.name, pci_data.instance))
1480 == (dev_info_t *)NULL) {
1481 rc = ENXIO;
1482 return (rc);
1483 } else {
1484 if (ddi_getprop(DDI_DEV_T_ANY,
1485 child_dip, DDI_PROP_DONTPASS,
1486 "vendor-id", DB_INVAL_VEND)
1487 == DB_INVAL_VEND) {
1488 /* non PCI device */
1489 rc = EINVAL;
1490 return (rc);
1491 }
1492 }
1493 }
1494 pci_data.instance = ddi_get_instance(child_dip);
1495 (void) pci_config_setup(child_dip, &config_handle);
1496 db_pci_get_header(config_handle, &pci_data.pri_hdr, 0);
1497
1498 /* if it is the drawbridge itself, read sec header */
1499 if (child_dip == dbp->dip) {
1500 db_pci_get_header(config_handle,
1501 &pci_data.sec_hdr, DB_PCONF_SEC_HDR_OFF);
1502 db_pci_get_conf_regs(config_handle,
1503 &pci_data.conf_regs);
1504 }
1505 pci_config_teardown(&config_handle);
1506
1507 if (ddi_copyout((caddr_t)&pci_data, (caddr_t)arg,
1508 sizeof (db_pci_data_t), mode)) {
1509 rc = EFAULT;
1510 return (rc);
1511 }
1512
1513 return (rc);
1514 }
1515 #endif /* DB_DEBUG */
1516
1517 /*
1518 * if secondary nexus (hotplug), then use pcihp_ioctl to do everything
1519 */
1520 if (dbp->dev_state & DB_SECONDARY_NEXUS)
1521 return ((pcihp_get_cb_ops())->cb_ioctl(dev, cmd,
1522 arg, mode, cred_p, rval_p));
1523
1524 /*
1525 * if not secondary nexus, we do DEVCTL_DEVICE and DEVCTL_BUS ourselves
1526 */
1527 self = dbp->dip;
1528
1529 /*
1530 * We can use the generic implementation for these ioctls
1531 */
1532 switch (cmd) {
1533 case DEVCTL_DEVICE_GETSTATE:
1534 case DEVCTL_DEVICE_ONLINE:
1535 case DEVCTL_DEVICE_OFFLINE:
1536 case DEVCTL_BUS_GETSTATE:
1537 return (ndi_devctl_ioctl(self, cmd, arg, mode, 0));
1538 }
1539
1540 /*
1541 * read devctl ioctl data
1542 */
1543 if (ndi_dc_allochdl((void *)arg, &dcp) != NDI_SUCCESS)
1544 return (EFAULT);
1545
1546 switch (cmd) {
1547
1548 case DEVCTL_DEVICE_RESET:
1549 rc = ENOTSUP;
1550 break;
1551
1552
1553 case DEVCTL_BUS_QUIESCE:
1554 if (ndi_get_bus_state(self, &bus_state) == NDI_SUCCESS)
1555 if (bus_state == BUS_QUIESCED)
1556 break;
1557 (void) ndi_set_bus_state(self, BUS_QUIESCED);
1558 break;
1559
1560 case DEVCTL_BUS_UNQUIESCE:
1561 if (ndi_get_bus_state(self, &bus_state) == NDI_SUCCESS)
1562 if (bus_state == BUS_ACTIVE)
1563 break;
1564 (void) ndi_set_bus_state(self, BUS_ACTIVE);
1565 break;
1566
1567 case DEVCTL_BUS_RESET:
1568 rc = ENOTSUP;
1569 break;
1570
1571 case DEVCTL_BUS_RESETALL:
1572 rc = ENOTSUP;
1573 break;
1574
1575 default:
1576 rc = ENOTTY;
1577 }
1578
1579 ndi_dc_freehdl(dcp);
1580 return (rc);
1581 }
1582
1583 #ifdef DB_DEBUG
1584 static dev_info_t *
db_lookup_child_name(db_ctrl_t * dbp,char * name,int instance)1585 db_lookup_child_name(db_ctrl_t *dbp, char *name, int instance)
1586 {
1587 dev_info_t *cdip, *pdip = dbp->dip;
1588
1589 for (cdip = ddi_get_child(pdip); cdip;
1590 cdip = ddi_get_next_sibling(pdip)) {
1591
1592 do {
1593 if (strcmp(ddi_node_name(cdip), name) == 0) {
1594 if (instance != -1) {
1595 if (ddi_get_instance(cdip) == instance)
1596 return (cdip);
1597 } else
1598 return (cdip);
1599 }
1600 pdip = cdip;
1601 } while ((cdip = ddi_get_child(pdip)));
1602 cdip = ddi_get_next_sibling(pdip);
1603 if (cdip == NULL) {
1604 pdip = ddi_get_parent(pdip);
1605 if (pdip == dbp->dip)
1606 break;
1607 }
1608 }
1609 return (NULL);
1610 }
1611
1612 static void
db_pci_get_header(ddi_acc_handle_t config_handle,db_pci_header_t * ph,off_t hdr_off)1613 db_pci_get_header(ddi_acc_handle_t config_handle, db_pci_header_t *ph,
1614 off_t hdr_off)
1615 {
1616 ph->venid = pci_config_get16(config_handle, hdr_off + PCI_CONF_VENID);
1617 ph->devid = pci_config_get16(config_handle, hdr_off + PCI_CONF_DEVID);
1618 ph->command = pci_config_get16(config_handle, hdr_off + PCI_CONF_COMM);
1619 ph->status = pci_config_get16(config_handle, hdr_off + PCI_CONF_STAT);
1620 ph->revid = pci_config_get8(config_handle, hdr_off + PCI_CONF_REVID);
1621 ph->pif = pci_config_get8(config_handle, hdr_off + PCI_CONF_PROGCLASS);
1622 ph->subclass = pci_config_get8(config_handle,
1623 hdr_off + PCI_CONF_SUBCLASS);
1624 ph->class = pci_config_get8(config_handle,
1625 hdr_off + PCI_CONF_BASCLASS);
1626 ph->cacheline = pci_config_get8(config_handle,
1627 hdr_off + PCI_CONF_CACHE_LINESZ);
1628 ph->lat = pci_config_get8(config_handle,
1629 hdr_off + PCI_CONF_LATENCY_TIMER);
1630 ph->hdr_type = pci_config_get8(config_handle,
1631 hdr_off + PCI_CONF_HEADER);
1632 ph->bist = pci_config_get8(config_handle, hdr_off + PCI_CONF_BIST);
1633 ph->bar0 = pci_config_get32(config_handle, hdr_off + PCI_CONF_BASE0);
1634 ph->bar1 = pci_config_get32(config_handle, hdr_off + PCI_CONF_BASE1);
1635 ph->bar2 = pci_config_get32(config_handle, hdr_off + PCI_CONF_BASE2);
1636 ph->bar3 = pci_config_get32(config_handle, hdr_off + PCI_CONF_BASE3);
1637 ph->bar4 = pci_config_get32(config_handle, hdr_off + PCI_CONF_BASE4);
1638 ph->bar5 = pci_config_get32(config_handle, hdr_off + PCI_CONF_BASE5);
1639 ph->cardbus_cisp = pci_config_get32(config_handle,
1640 hdr_off + PCI_CONF_CIS);
1641 ph->sub_venid = pci_config_get16(config_handle,
1642 hdr_off + PCI_CONF_SUBVENID);
1643 ph->sub_devid = pci_config_get16(config_handle,
1644 hdr_off + PCI_CONF_SUBSYSID);
1645 ph->exprom_bar = pci_config_get32(config_handle,
1646 hdr_off + PCI_CONF_ROM);
1647 ph->int_line = pci_config_get8(config_handle, hdr_off + PCI_CONF_ILINE);
1648 ph->int_pin = pci_config_get8(config_handle, hdr_off + PCI_CONF_IPIN);
1649 ph->min_gnt = pci_config_get8(config_handle, hdr_off + PCI_CONF_MIN_G);
1650 ph->max_lat = pci_config_get8(config_handle, hdr_off + PCI_CONF_MAX_L);
1651 }
1652
1653 static void
db_pci_get_conf_regs(ddi_acc_handle_t config_handle,db_conf_regs_t * cr)1654 db_pci_get_conf_regs(ddi_acc_handle_t config_handle, db_conf_regs_t *cr)
1655 {
1656 cr->ds_mem0_tr_base = pci_config_get32(config_handle,
1657 DB_CONF_DS_MEM0_TR_BASE);
1658 cr->ds_io_mem1_tr_base = pci_config_get32(config_handle,
1659 DB_CONF_DS_IO_MEM1_TR_BASE);
1660 cr->ds_mem2_tr_base = pci_config_get32(config_handle,
1661 DB_CONF_DS_MEM2_TR_BASE);
1662 cr->ds_mem3_tr_base = pci_config_get32(config_handle,
1663 DB_CONF_DS_MEM3_TR_BASE);
1664 cr->us_io_mem0_tr_base = pci_config_get32(config_handle,
1665 DB_CONF_US_IO_MEM0_TR_BASE);
1666 cr->us_mem1_tr_base = pci_config_get32(config_handle,
1667 DB_CONF_US_MEM1_TR_BASE);
1668 cr->ds_mem0_setup_reg = pci_config_get32(config_handle,
1669 DB_CONF_DS_MEM0_SETUP);
1670 cr->ds_io_mem1_setup_reg = pci_config_get32(config_handle,
1671 DB_CONF_DS_IO_MEM1_SETUP);
1672 cr->ds_mem2_setup_reg = pci_config_get32(config_handle,
1673 DB_CONF_DS_MEM2_SETUP);
1674 cr->ds_mem3_setup_reg = pci_config_get64(config_handle,
1675 DB_CONF_DS_MEM3_SETUP);
1676 cr->p_exp_rom_setup = pci_config_get32(config_handle,
1677 DB_CONF_PRIM_EXP_ROM_SETUP);
1678 cr->us_io_mem0_setup_reg = pci_config_get32(config_handle,
1679 DB_CONF_US_IO_MEM0_SETUP);
1680 cr->us_mem1_setup_reg = pci_config_get32(config_handle,
1681 DB_CONF_US_MEM1_SETUP);
1682 cr->chip_control0 = pci_config_get16(config_handle, DB_CONF_CHIP_CTRL0);
1683 cr->chip_control1 = pci_config_get16(config_handle, DB_CONF_CHIP_CTRL1);
1684 cr->chip_status = pci_config_get16(config_handle, DB_CONF_STATUS);
1685 cr->arb_control = pci_config_get16(config_handle, DB_CONF_ARBITER_CTRL);
1686 cr->p_serr_disables = pci_config_get8(config_handle,
1687 DB_CONF_PRIM_SERR_DISABLES);
1688 cr->s_serr_disables = pci_config_get8(config_handle,
1689 DB_CONF_PRIM_SERR_DISABLES);
1690 cr->config_csr = pci_config_get16(config_handle, DB_CONF_CONF_CSR);
1691 cr->reset_control = pci_config_get32(config_handle, DB_CONF_RESET_CTRL);
1692 cr->pm_cap = pci_config_get16(config_handle, DB_CONF_PM_CAP);
1693 cr->pm_csr = pci_config_get16(config_handle, DB_CONF_PM_CSR);
1694 cr->hs_csr = pci_config_get8(config_handle, DB_CONF_HS_CSR);
1695 }
1696 #endif /* DB_DEBUG */
1697
1698 /*
1699 * Function: db_pci_map
1700 *
1701 * Note: Only memory accesses are direct. IO could be direct
1702 * or indirect. Config accesses are always indirect.
1703 * The question here is, does the "assigned-addresses"
1704 * property entry represents the addresses in the
1705 * local domain or the host domain itself.
1706 * Strictly speaking, the assumption should be that
1707 * it is in the local domain, as the transactions
1708 * upstream or downstream are automatically
1709 * translated by the bridge chip anyway.
1710 *
1711 * Return values:
1712 * DDI_SUCCESS: map call by child device success
1713 * DDI_FAILURE: map operation failed.
1714 */
1715
1716 static int
db_pci_map(dev_info_t * dip,dev_info_t * rdip,ddi_map_req_t * mp,off_t offset,off_t len,caddr_t * addrp)1717 db_pci_map(dev_info_t *dip, dev_info_t *rdip, ddi_map_req_t *mp,
1718 off_t offset, off_t len, caddr_t *addrp)
1719 {
1720 register dev_info_t *pdip;
1721 int reg_proplen, num_regs, rnumber;
1722 uint_t addr_space_type;
1723 pci_regspec_t *pci_regsetp, pci_reg;
1724 db_ctrl_t *dbp;
1725 db_acc_pvt_t *db_pvt;
1726 ddi_acc_impl_t *ap;
1727 ddi_acc_hdl_t *hp;
1728 db_acc_cfg_addr_t *pci_addr;
1729 int instance = ddi_get_instance(dip);
1730
1731 DB_DEBUG0(DB_PCI_MAP, dip, "enter\n");
1732
1733 /* get map type. check for config space */
1734 switch (mp->map_type) {
1735
1736 case DDI_MT_RNUMBER :
1737 /* get the reg number */
1738 rnumber = mp->map_obj.rnumber;
1739
1740 if (ddi_getlongprop(DDI_DEV_T_ANY, rdip,
1741 DDI_PROP_DONTPASS, "reg",
1742 (caddr_t)&pci_regsetp, ®_proplen)
1743 != DDI_SUCCESS)
1744 return (DDI_FAILURE);
1745
1746 num_regs = reg_proplen / (int)sizeof (pci_regspec_t);
1747 if (rnumber >= num_regs) {
1748 /* this is a DDI_ME_RNUMBER_RANGE error */
1749 kmem_free(pci_regsetp, reg_proplen);
1750 return (DDI_FAILURE);
1751 }
1752
1753 pci_reg = pci_regsetp[rnumber];
1754 kmem_free(pci_regsetp, reg_proplen);
1755 /* FALLTHROUGH */
1756 case DDI_MT_REGSPEC :
1757 if (mp->map_type == DDI_MT_REGSPEC)
1758 pci_reg = *(pci_regspec_t *)mp->map_obj.rp;
1759
1760 /*
1761 * Intercept config space accesses only. All other
1762 * requests go to the parent.
1763 */
1764 addr_space_type = pci_reg.pci_phys_hi & PCI_ADDR_MASK;
1765
1766 DB_DEBUG3(DB_PCI_MAP, dip, "rdip=%lx, rnum=%d(%d)\n",
1767 rdip, rnumber, num_regs);
1768
1769 /* if we do direct map IO, then lets break here */
1770 if ((db_io_map_mode & DB_IO_MAP_DIRECT) &&
1771 (addr_space_type == PCI_ADDR_IO))
1772 break;
1773
1774 if ((addr_space_type != PCI_ADDR_CONFIG) &&
1775 (addr_space_type != PCI_ADDR_IO))
1776 break;
1777
1778 /*
1779 * User mapping requests not legal for indirect
1780 * IO/Config Space
1781 */
1782 if (mp->map_op == DDI_MO_MAP_HANDLE)
1783 return (DDI_FAILURE);
1784
1785 dbp = (db_ctrl_t *)ddi_get_soft_state(db_state,
1786 instance);
1787 /* get our common access handle */
1788 hp = (ddi_acc_hdl_t *)mp->map_handlep;
1789
1790 /* Check for unmap operation */
1791 if ((mp->map_op == DDI_MO_UNMAP) ||
1792 (mp->map_op == DDI_MO_UNLOCK)) {
1793 /*
1794 * free up memory allocated for our
1795 * private access handle.
1796 */
1797 db_pvt = (db_acc_pvt_t *)
1798 hp->ah_bus_private;
1799 DB_DEBUG1(DB_PCI_MAP, dip,
1800 "unmap rdip=%lx\n", rdip);
1801 kmem_free((void *)db_pvt,
1802 sizeof (db_acc_pvt_t));
1803
1804 /*
1805 * unmap operation of PCI IO/config
1806 * space.
1807 */
1808 return (DDI_SUCCESS);
1809 }
1810
1811 if (addr_space_type == PCI_ADDR_CONFIG) {
1812 /* Config space access range check */
1813 if ((offset >= PCI_CONF_HDR_SIZE) ||
1814 (len > PCI_CONF_HDR_SIZE) ||
1815 (offset + len > PCI_CONF_HDR_SIZE)) {
1816
1817 return (DDI_FAILURE);
1818 }
1819 }
1820
1821 /* define the complete access handle */
1822 hp = (ddi_acc_hdl_t *)mp->map_handlep;
1823
1824 ap = (ddi_acc_impl_t *)hp->ah_platform_private;
1825
1826 ap->ahi_get8 = db_ddi_get8;
1827 ap->ahi_get16 = db_ddi_get16;
1828 ap->ahi_get32 = db_ddi_get32;
1829 ap->ahi_get64 = db_ddi_get64;
1830 ap->ahi_put8 = db_ddi_put8;
1831 ap->ahi_put16 = db_ddi_put16;
1832 ap->ahi_put32 = db_ddi_put32;
1833 ap->ahi_put64 = db_ddi_put64;
1834 ap->ahi_rep_get8 = db_ddi_rep_get8;
1835 ap->ahi_rep_get16 = db_ddi_rep_get16;
1836 ap->ahi_rep_get32 = db_ddi_rep_get32;
1837 ap->ahi_rep_get64 = db_ddi_rep_get64;
1838 ap->ahi_rep_put8 = db_ddi_rep_put8;
1839 ap->ahi_rep_put16 = db_ddi_rep_put16;
1840 ap->ahi_rep_put32 = db_ddi_rep_put32;
1841 ap->ahi_rep_put64 = db_ddi_rep_put64;
1842
1843 /* Initialize to default check/notify functions */
1844 ap->ahi_fault = 0;
1845 ap->ahi_fault_check = i_ddi_acc_fault_check;
1846 ap->ahi_fault_notify = i_ddi_acc_fault_notify;
1847
1848 /* allocate memory for our private handle */
1849 db_pvt = kmem_zalloc(sizeof (db_acc_pvt_t), KM_SLEEP);
1850 hp->ah_bus_private = (void *)db_pvt;
1851 db_pvt->dbp = dbp;
1852
1853 /* record the device address for future use */
1854 pci_addr = &db_pvt->dev_addr;
1855 pci_addr->c_busnum =
1856 PCI_REG_BUS_G(pci_reg.pci_phys_hi);
1857 pci_addr->c_devnum =
1858 PCI_REG_DEV_G(pci_reg.pci_phys_hi);
1859 pci_addr->c_funcnum =
1860 PCI_REG_FUNC_G(pci_reg.pci_phys_hi);
1861 /*
1862 * We should keep the upstream or
1863 * downstream info in our own ah_bus_private
1864 * structure, so that we do not waste our
1865 * time in the actual IO routines, figuring out
1866 * if we should use upstream or downstream
1867 * configuration addr/data register.
1868 * So, check orientation and setup registers
1869 * right now.
1870 */
1871 switch (addr_space_type) {
1872
1873 case PCI_ADDR_CONFIG :
1874 if (dbp->dev_state & DB_PRIMARY_NEXUS) {
1875 DB_DEBUG0(DB_PCI_MAP, dip, "primary\n");
1876 db_pvt->mask = DS8_CONF_OWN;
1877 if (db_conf_map_mode &
1878 DB_CONF_MAP_INDIRECT_IO) {
1879 DB_DEBUG0(DB_PCI_MAP, dip,
1880 "INDIRECT_CONF\n");
1881
1882 db_pvt->handle =
1883 dbp->csr_io_handle;
1884 db_pvt->addr =
1885 (uint32_t *)
1886 ((uchar_t *)dbp->csr_io
1887 + DB_CSR_DS_CONF_ADDR);
1888 db_pvt->data =
1889 (uint32_t *)
1890 ((uchar_t *)dbp->csr_io
1891 + DB_CSR_DS_CONF_DATA);
1892 db_pvt->bus_own =
1893 (uint8_t *)
1894 ((uchar_t *)dbp->csr_io
1895 + DB_CSR8_DS_CONF_OWN);
1896 db_pvt->bus_release =
1897 (uint8_t *)
1898 ((uchar_t *)dbp->csr_io
1899 + DB_CSR8_DS_CONF_CSR);
1900 } else {
1901 DB_DEBUG0(DB_PCI_MAP, dip,
1902 "DIRECT_CONF\n");
1903
1904 db_pvt->handle =
1905 dbp->conf_handle;
1906 db_pvt->addr =
1907 (uint32_t *)
1908 ((uchar_t *)dbp->conf_io
1909 + DB_CONF_DS_CONF_ADDR);
1910 db_pvt->data = (uint32_t *)
1911 ((uchar_t *)dbp->conf_io
1912 + DB_CONF_DS_CONF_DATA);
1913 db_pvt->bus_own =
1914 (uint8_t *)
1915 ((uchar_t *)dbp->conf_io
1916 + DB_CONF8_DS_CONF_OWN);
1917 db_pvt->bus_release =
1918 (uint8_t *)
1919 ((uchar_t *)dbp->conf_io
1920 + DB_CONF8_DS_CONF_CSR);
1921 }
1922 } else {
1923 DB_DEBUG0(DB_PCI_MAP, dip,
1924 "secondary\n");
1925 db_pvt->mask = US8_CONF_OWN;
1926 if (db_conf_map_mode &
1927 DB_CONF_MAP_INDIRECT_IO) {
1928 DB_DEBUG0(DB_PCI_MAP, dip,
1929 "INDIRECT_CONF\n");
1930
1931 db_pvt->handle =
1932 dbp->csr_io_handle;
1933 db_pvt->addr =
1934 (uint32_t *)
1935 ((uchar_t *)dbp->csr_io
1936 + DB_CSR_US_CONF_ADDR);
1937 db_pvt->data =
1938 (uint32_t *)
1939 ((uchar_t *)dbp->csr_io
1940 + DB_CSR_US_CONF_DATA);
1941 db_pvt->bus_own =
1942 (uint8_t *)
1943 ((uchar_t *)dbp->csr_io
1944 + DB_CSR8_US_CONF_OWN);
1945 db_pvt->bus_release =
1946 (uint8_t *)
1947 ((uchar_t *)dbp->csr_io
1948 + DB_CSR8_US_CONF_CSR);
1949 } else {
1950 DB_DEBUG0(DB_PCI_MAP, dip,
1951 "DIRECT_CONF\n");
1952
1953 db_pvt->handle =
1954 dbp->conf_handle;
1955 db_pvt->addr =
1956 (uint32_t *)
1957 ((uchar_t *)dbp->conf_io
1958 + DB_CONF_US_CONF_ADDR);
1959 db_pvt->data =
1960 (uint32_t *)
1961 ((uchar_t *)dbp->conf_io
1962 + DB_CONF_US_CONF_DATA);
1963 db_pvt->bus_own =
1964 (uint8_t *)
1965 ((uchar_t *)dbp->conf_io
1966 + DB_CONF8_US_CONF_OWN);
1967 db_pvt->bus_release =
1968 (uint8_t *)
1969 ((uchar_t *)dbp->conf_io
1970 + DB_CONF8_US_CONF_CSR);
1971 }
1972 }
1973 break;
1974
1975 case PCI_ADDR_IO :
1976 DB_DEBUG0(DB_PCI_MAP, dip, "PCI_ADDR_IO\n");
1977
1978 /* ap->ahi_acc_attr |= DDI_ACCATTR_IO_SPACE; */
1979 db_pvt->handle = dbp->csr_io_handle;
1980 if (dbp->dev_state & DB_PRIMARY_NEXUS) {
1981 DB_DEBUG0(DB_PCI_MAP, dip, "primary\n");
1982 db_pvt->addr = (uint32_t *)
1983 ((uchar_t *)dbp->csr_io
1984 + DB_CSR_DS_IO_ADDR);
1985 db_pvt->data = (uint32_t *)
1986 ((uchar_t *)dbp->csr_io
1987 + DB_CSR_DS_IO_DATA);
1988 db_pvt->bus_own = (uint8_t *)
1989 ((uchar_t *)dbp->csr_io
1990 + DB_CSR8_DS_IO_OWN);
1991 db_pvt->bus_release = (uint8_t *)
1992 ((uchar_t *)dbp->csr_io
1993 + DB_CSR8_DS_IO_CSR);
1994 db_pvt->mask = DS8_IO_OWN;
1995 } else {
1996 DB_DEBUG0(DB_PCI_MAP, dip,
1997 "secondary\n");
1998 db_pvt->addr = (uint32_t *)
1999 ((uchar_t *)dbp->csr_io
2000 + DB_CSR_US_IO_ADDR);
2001 db_pvt->data = (uint32_t *)
2002 ((uchar_t *)dbp->csr_io
2003 + DB_CSR_US_IO_DATA);
2004 db_pvt->bus_own = (uint8_t *)
2005 ((uchar_t *)dbp->csr_io
2006 + DB_CSR8_US_IO_OWN);
2007 db_pvt->bus_release = (uint8_t *)
2008 ((uchar_t *)dbp->csr_io
2009 + DB_CSR8_US_IO_CSR);
2010 db_pvt->mask = US8_IO_OWN;
2011 }
2012 break;
2013
2014 default :
2015 DB_DEBUG0(DB_PCI_MAP, dip,
2016 "PCI_ADDR unknown\n");
2017 break;
2018 }
2019
2020 /* make and store a type 0/1 address in the *addrp */
2021 if (pci_addr->c_busnum == dbp->range.lo) {
2022 *addrp = (caddr_t)DB_PCI_REG_ADDR_TYPE0(
2023 pci_addr->c_busnum,
2024 pci_addr->c_devnum,
2025 pci_addr->c_funcnum,
2026 offset);
2027 db_pvt->access_mode |= DB_PCI_CONF_CYCLE_TYPE0;
2028 DB_DEBUG0(DB_PCI_MAP, dip,
2029 "access mode type 0\n");
2030 } else {
2031 *addrp = (caddr_t)DB_PCI_REG_ADDR_TYPE1(
2032 pci_addr->c_busnum,
2033 pci_addr->c_devnum,
2034 pci_addr->c_funcnum,
2035 offset);
2036 db_pvt->access_mode |= DB_PCI_CONF_CYCLE_TYPE1;
2037 DB_DEBUG0(DB_PCI_MAP, dip,
2038 "access mode type 1\n");
2039 }
2040 DB_DEBUG4(DB_PCI_MAP, dip, "addrp<%x,%x,%x> = %lx\n",
2041 pci_addr->c_busnum, pci_addr->c_devnum,
2042 pci_addr->c_funcnum, *addrp);
2043
2044 return (DDI_SUCCESS);
2045
2046 default :
2047 DB_DEBUG1(DB_PCI_MAP, dip, "DDI other %x\n",
2048 mp->map_type);
2049 break;
2050 }
2051 DB_DEBUG0(DB_PCI_MAP, dip, "exit\n");
2052
2053 pdip = (dev_info_t *)DEVI(dip)->devi_parent;
2054 return ((DEVI(pdip)->devi_ops->devo_bus_ops->bus_map)
2055 (pdip, rdip, mp, offset, len, addrp));
2056 }
2057
2058 #ifdef DB_DEBUG
2059 char *db_ctlop_name[] = {
2060 "DDI_CTLOPS_DMAPMAPC",
2061 "DDI_CTLOPS_INITCHILD",
2062 "DDI_CTLOPS_UNINITCHILD",
2063 "DDI_CTLOPS_REPORTDEV",
2064 "DDI_CTLOPS_REPORTINT",
2065 "DDI_CTLOPS_REGSIZE",
2066 "DDI_CTLOPS_NREGS",
2067 "DDI_CTLOPS_RESERVED0",
2068 "DDI_CTLOPS_SIDDEV",
2069 "DDI_CTLOPS_SLAVEONLY",
2070 "DDI_CTLOPS_AFFINITY",
2071 "DDI_CTLOPS_IOMIN",
2072 "DDI_CTLOPS_PTOB",
2073 "DDI_CTLOPS_BTOP",
2074 "DDI_CTLOPS_BTOPR",
2075 "DDI_CTLOPS_RESERVED1",
2076 "DDI_CTLOPS_RESERVED2",
2077 "DDI_CTLOPS_RESERVED3",
2078 "DDI_CTLOPS_RESERVED4",
2079 "DDI_CTLOPS_RESERVED5",
2080 "DDI_CTLOPS_DVMAPAGESIZE",
2081 "DDI_CTLOPS_POWER",
2082 "DDI_CTLOPS_ATTACH",
2083 "DDI_CTLOPS_DETACH",
2084 "DDI_CTLOPS_POKE",
2085 "DDI_CTLOPS_PEEK"
2086 };
2087 #endif
2088
2089 static int
db_ctlops(dev_info_t * dip,dev_info_t * rdip,ddi_ctl_enum_t ctlop,void * arg,void * result)2090 db_ctlops(dev_info_t *dip, dev_info_t *rdip,
2091 ddi_ctl_enum_t ctlop, void *arg, void *result)
2092 {
2093
2094 if ((ctlop >= DDI_CTLOPS_DMAPMAPC) &&
2095 (ctlop <= DDI_CTLOPS_DETACH)) {
2096 DB_DEBUG1(DB_CTLOPS, dip, "ctlop=%s\n", db_ctlop_name[ctlop]);
2097 } else {
2098 DB_DEBUG1(DB_CTLOPS, dip, "ctlop=%d\n", ctlop);
2099 }
2100
2101 switch (ctlop) {
2102 case DDI_CTLOPS_REPORTDEV :
2103 if (rdip == (dev_info_t *)0)
2104 return (DDI_FAILURE);
2105 cmn_err(CE_CONT, "?PCI-device: %s@%s, %s#%d\n",
2106 ddi_node_name(rdip), ddi_get_name_addr(rdip),
2107 ddi_driver_name(rdip),
2108 ddi_get_instance(rdip));
2109 return (DDI_SUCCESS);
2110
2111 case DDI_CTLOPS_INITCHILD :
2112 return (db_initchild((dev_info_t *)arg));
2113
2114 case DDI_CTLOPS_UNINITCHILD :
2115 db_uninitchild((dev_info_t *)arg);
2116 return (DDI_SUCCESS);
2117
2118 case DDI_CTLOPS_SIDDEV :
2119 return (DDI_SUCCESS);
2120
2121 case DDI_CTLOPS_REGSIZE :
2122 case DDI_CTLOPS_NREGS :
2123 if (rdip == (dev_info_t *)0)
2124 return (DDI_FAILURE);
2125 /* fall through */
2126
2127 default :
2128 return (ddi_ctlops(dip, rdip, ctlop, arg, result));
2129 }
2130
2131 }
2132
2133 static dev_info_t *
db_get_my_childs_dip(dev_info_t * dip,dev_info_t * rdip)2134 db_get_my_childs_dip(dev_info_t *dip, dev_info_t *rdip)
2135 {
2136 dev_info_t *cdip = rdip;
2137
2138 for (; ddi_get_parent(cdip) != dip; cdip = ddi_get_parent(cdip))
2139 ;
2140
2141 return (cdip);
2142 }
2143
2144 static int
db_intr_ops(dev_info_t * dip,dev_info_t * rdip,ddi_intr_op_t intr_op,ddi_intr_handle_impl_t * hdlp,void * result)2145 db_intr_ops(dev_info_t *dip, dev_info_t *rdip, ddi_intr_op_t intr_op,
2146 ddi_intr_handle_impl_t *hdlp, void *result)
2147 {
2148 dev_info_t *cdip = rdip;
2149 pci_regspec_t *pci_rp;
2150 int reglen, len;
2151 uint32_t d, intr;
2152
2153 DB_DEBUG1(DB_INTR_OPS, dip, "intr_op=%d\n", intr_op);
2154
2155 if ((intr_op == DDI_INTROP_SUPPORTED_TYPES) ||
2156 (hdlp->ih_type != DDI_INTR_TYPE_FIXED))
2157 goto done;
2158
2159 /*
2160 * If the interrupt-map property is defined at this
2161 * node, it will have performed the interrupt
2162 * translation as part of the property, so no
2163 * rotation needs to be done.
2164 */
2165
2166 if (ddi_getproplen(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
2167 "interrupt-map", &len) == DDI_PROP_SUCCESS)
2168 goto done;
2169
2170 cdip = db_get_my_childs_dip(dip, rdip);
2171
2172 /*
2173 * Use the devices reg property to determine it's
2174 * PCI bus number and device number.
2175 */
2176 if (ddi_getlongprop(DDI_DEV_T_ANY, cdip, DDI_PROP_DONTPASS,
2177 "reg", (caddr_t)&pci_rp, ®len) != DDI_SUCCESS)
2178 return (DDI_FAILURE);
2179
2180 intr = hdlp->ih_vector;
2181
2182 /* Spin the interrupt */
2183 d = PCI_REG_DEV_G(pci_rp[0].pci_phys_hi);
2184
2185 if ((intr >= PCI_INTA) && (intr <= PCI_INTD))
2186 hdlp->ih_vector = ((intr - 1 + (d % 4)) % 4 + 1);
2187 else
2188 cmn_err(CE_WARN, "%s#%d: %s: PCI intr=%x out of range",
2189 ddi_driver_name(rdip), ddi_get_instance(rdip),
2190 ddi_driver_name(dip), intr);
2191
2192 DB_DEBUG3(DB_INTR_OPS, dip, "intr=%d, d=%d, is_intr=%d\n",
2193 intr, d, hdlp->ih_vector);
2194
2195 kmem_free(pci_rp, reglen);
2196
2197 done:
2198 /* Pass up the request to our parent. */
2199 return (i_ddi_intr_ops(dip, rdip, intr_op, hdlp, result));
2200 }
2201
2202 static int
db_name_child(dev_info_t * child,char * name,int namelen)2203 db_name_child(dev_info_t *child, char *name, int namelen)
2204 {
2205 uint_t n, slot, func;
2206 pci_regspec_t *pci_rp;
2207
2208 if (ndi_dev_is_persistent_node(child) == 0) {
2209 char **unit_addr;
2210
2211 /* name .conf nodes by "unit-address" property" */
2212 if (ddi_prop_lookup_string_array(DDI_DEV_T_ANY, child,
2213 DDI_PROP_DONTPASS, "unit-address", &unit_addr, &n) !=
2214 DDI_PROP_SUCCESS) {
2215 cmn_err(CE_WARN, "cannot name node from %s.conf",
2216 ddi_driver_name(child));
2217 return (DDI_FAILURE);
2218 }
2219 if (n != 1 || *unit_addr == NULL || **unit_addr == 0) {
2220 cmn_err(CE_WARN, "unit-address property in %s.conf"
2221 " not well-formed", ddi_driver_name(child));
2222 ddi_prop_free(unit_addr);
2223 return (DDI_FAILURE);
2224 }
2225
2226 (void) snprintf(name, namelen, "%s", *unit_addr);
2227 ddi_prop_free(unit_addr);
2228 return (DDI_SUCCESS);
2229 }
2230
2231 /* name hardware nodes by "reg" property */
2232 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, child, 0, "reg",
2233 (int **)&pci_rp, &n) != DDI_SUCCESS)
2234 return (DDI_FAILURE);
2235
2236 /* get the device identifications */
2237 slot = PCI_REG_DEV_G(pci_rp->pci_phys_hi);
2238 func = PCI_REG_FUNC_G(pci_rp->pci_phys_hi);
2239
2240 if (func != 0)
2241 (void) snprintf(name, namelen, "%x,%x", slot, func);
2242 else
2243 (void) snprintf(name, namelen, "%x", slot);
2244
2245 ddi_prop_free(pci_rp);
2246 return (DDI_SUCCESS);
2247 }
2248
2249 static int
db_initchild(dev_info_t * child)2250 db_initchild(dev_info_t *child)
2251 {
2252 char name[MAXNAMELEN];
2253 ddi_acc_handle_t config_handle;
2254 ushort_t command_preserve, command;
2255 uint_t n;
2256 ushort_t bcr;
2257 uchar_t header_type, min_gnt, latency_timer;
2258 db_ctrl_t *dbp;
2259
2260 if (db_name_child(child, name, MAXNAMELEN) != DDI_SUCCESS)
2261 return (DDI_FAILURE);
2262
2263 ddi_set_name_addr(child, name);
2264 ddi_set_parent_data(child, NULL);
2265
2266 /*
2267 * Pseudo nodes indicate a prototype node with per-instance
2268 * properties to be merged into the real h/w device node.
2269 * The interpretation of the unit-address is DD[,F]
2270 * where DD is the device id and F is the function.
2271 */
2272 if (ndi_dev_is_persistent_node(child) == 0) {
2273 extern int pci_allow_pseudo_children;
2274
2275 /*
2276 * Try to merge the properties from this prototype
2277 * node into real h/w nodes.
2278 */
2279 if (ndi_merge_node(child, db_name_child) == DDI_SUCCESS) {
2280 /*
2281 * Merged ok - return failure to remove the node.
2282 */
2283 return (DDI_FAILURE);
2284 }
2285
2286 /* workaround for ddivs to run under PCI */
2287 if (pci_allow_pseudo_children) {
2288 return (DDI_SUCCESS);
2289 }
2290
2291 /*
2292 * The child was not merged into a h/w node,
2293 * but there's not much we can do with it other
2294 * than return failure to cause the node to be removed.
2295 */
2296 cmn_err(CE_WARN, "!%s@%s: %s.conf properties not merged",
2297 ddi_driver_name(child), ddi_get_name_addr(child),
2298 ddi_driver_name(child));
2299 return (DDI_NOT_WELL_FORMED);
2300 }
2301
2302
2303 if ((db_create_pci_prop(child) != DDI_SUCCESS) ||
2304 (pci_config_setup(child, &config_handle) != DDI_SUCCESS)) {
2305 db_uninitchild(child);
2306 return (DDI_FAILURE);
2307 }
2308
2309 /*
2310 * Determine the configuration header type.
2311 */
2312 header_type = pci_config_get8(config_handle, PCI_CONF_HEADER);
2313
2314 /*
2315 * Support for the "command-preserve" property.
2316 */
2317 command_preserve = ddi_prop_get_int(DDI_DEV_T_ANY, child,
2318 DDI_PROP_DONTPASS, "command-preserve", 0);
2319 command = pci_config_get16(config_handle, PCI_CONF_COMM);
2320 command &= (command_preserve | PCI_COMM_BACK2BACK_ENAB);
2321 command |= (db_command_default & ~command_preserve);
2322 pci_config_put16(config_handle, PCI_CONF_COMM, command);
2323
2324 DB_DEBUG2(DB_INITCHILD, ddi_get_parent(child),
2325 "initializing device vend=%x, devid=%x\n",
2326 pci_config_get16(config_handle, PCI_CONF_VENID),
2327 pci_config_get16(config_handle, PCI_CONF_DEVID));
2328 /*
2329 * If the device has a bus control register then program it
2330 * based on the settings in the command register.
2331 */
2332 if ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE) {
2333 bcr = pci_config_get8(config_handle, PCI_BCNF_BCNTRL);
2334 if (db_command_default & PCI_COMM_PARITY_DETECT)
2335 bcr |= PCI_BCNF_BCNTRL_PARITY_ENABLE;
2336 if (db_command_default & PCI_COMM_SERR_ENABLE)
2337 bcr |= PCI_BCNF_BCNTRL_SERR_ENABLE;
2338 bcr |= PCI_BCNF_BCNTRL_MAST_AB_MODE;
2339 pci_config_put8(config_handle, PCI_BCNF_BCNTRL, bcr);
2340 }
2341
2342 dbp = (db_ctrl_t *)ddi_get_soft_state(db_state,
2343 ddi_get_instance(ddi_get_parent(child)));
2344
2345 /*
2346 * Initialize cache-line-size configuration register if needed.
2347 */
2348 if (db_set_cache_line_size_register &&
2349 ddi_getprop(DDI_DEV_T_ANY, child, DDI_PROP_DONTPASS,
2350 "cache-line-size", 0) == 0) {
2351 pci_config_put8(config_handle, PCI_CONF_CACHE_LINESZ,
2352 dbp->cache_line_size);
2353 n = pci_config_get8(config_handle, PCI_CONF_CACHE_LINESZ);
2354 if (n != 0) {
2355 (void) ndi_prop_update_int(DDI_DEV_T_NONE, child,
2356 "cache-line-size", n);
2357 }
2358 DB_DEBUG1(DB_INITCHILD, ddi_get_parent(child),
2359 "\nChild Device Cache Size %x\n", dbp->cache_line_size);
2360 }
2361
2362 /*
2363 * Initialize latency timer configuration registers if needed.
2364 */
2365 if (db_set_latency_timer_register &&
2366 ddi_getprop(DDI_DEV_T_ANY, child, DDI_PROP_DONTPASS,
2367 "latency-timer", 0) == 0) {
2368
2369 if ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE) {
2370 latency_timer = dbp->p_latency_timer;
2371 pci_config_put8(config_handle, PCI_BCNF_LATENCY_TIMER,
2372 dbp->latency_timer);
2373 } else {
2374 min_gnt = pci_config_get8(config_handle,
2375 PCI_CONF_MIN_G);
2376 latency_timer = min_gnt * 8;
2377 }
2378 pci_config_put8(config_handle, PCI_CONF_LATENCY_TIMER,
2379 latency_timer);
2380 n = pci_config_get8(config_handle, PCI_CONF_LATENCY_TIMER);
2381 if (n != 0) {
2382 (void) ndi_prop_update_int(DDI_DEV_T_NONE, child,
2383 "latency-timer", n);
2384 }
2385 DB_DEBUG1(DB_INITCHILD, ddi_get_parent(child),
2386 "\nChild Device latency %x\n", latency_timer);
2387 }
2388
2389 pci_config_teardown(&config_handle);
2390 return (DDI_SUCCESS);
2391 }
2392
2393 static void
db_uninitchild(dev_info_t * dip)2394 db_uninitchild(dev_info_t *dip)
2395 {
2396 ddi_set_name_addr(dip, NULL);
2397
2398 /*
2399 * Strip the node to properly convert it back to prototype form
2400 */
2401 impl_rem_dev_props(dip);
2402 }
2403
2404 static int
db_create_pci_prop(dev_info_t * child)2405 db_create_pci_prop(dev_info_t *child)
2406 {
2407 pci_regspec_t *pci_rp;
2408 int length;
2409 int value;
2410
2411 /* get child "reg" property */
2412 value = ddi_getlongprop(DDI_DEV_T_ANY, child, DDI_PROP_CANSLEEP,
2413 "reg", (caddr_t)&pci_rp, &length);
2414 if (value != DDI_SUCCESS)
2415 return (value);
2416
2417 (void) ndi_prop_update_byte_array(DDI_DEV_T_NONE, child, "reg",
2418 (uchar_t *)pci_rp, length);
2419
2420 /*
2421 * free the memory allocated by ddi_getlongprop ().
2422 */
2423 kmem_free(pci_rp, length);
2424
2425 /*
2426 * No need to create any 1275 properties here, because either
2427 * the OBP creates them or the hotplug framework creates it
2428 * during a hotplug operation. So lets return here.
2429 */
2430 return (DDI_SUCCESS);
2431 }
2432
2433 /*
2434 * db_save_config_regs
2435 *
2436 * This routine saves the state of the configuration registers of all
2437 * immediate child nodes.
2438 *
2439 * used by: db_detach() on suspends
2440 *
2441 * return value: DDI_SUCCESS: ALl children state saved.
2442 * DDI_FAILURE: Child device state could not be saved.
2443 */
2444 static int
db_save_config_regs(db_ctrl_t * dbp)2445 db_save_config_regs(db_ctrl_t *dbp)
2446 {
2447 int i;
2448 dev_info_t *dip;
2449 ddi_acc_handle_t config_handle;
2450 db_cfg_state_t *statep;
2451
2452 for (i = 0, dip = ddi_get_child(dbp->dip); dip != NULL;
2453 dip = ddi_get_next_sibling(dip)) {
2454 if (i_ddi_devi_attached(dip))
2455 i++;
2456 }
2457 dbp->config_state_index = i;
2458
2459 if (!i) {
2460 /* no children */
2461 dbp->db_config_state_p = NULL;
2462 return (DDI_SUCCESS);
2463 }
2464
2465 /* i now equals the total number of child devices */
2466 dbp->db_config_state_p =
2467 kmem_zalloc(i * sizeof (db_cfg_state_t), KM_NOSLEEP);
2468 if (!dbp->db_config_state_p) {
2469 cmn_err(CE_WARN,
2470 "%s#%d: No memory to save state for child %s#%d\n",
2471 ddi_driver_name(dbp->dip),
2472 ddi_get_instance(dbp->dip),
2473 ddi_get_name(dip), ddi_get_instance(dip));
2474 return (DDI_FAILURE);
2475 }
2476
2477 for (statep = dbp->db_config_state_p,
2478 dip = ddi_get_child(dbp->dip);
2479 dip != NULL;
2480 dip = ddi_get_next_sibling(dip)) {
2481
2482 if (!i_ddi_devi_attached(dip))
2483 continue;
2484
2485 if (pci_config_setup(dip, &config_handle) != DDI_SUCCESS) {
2486 cmn_err(CE_WARN,
2487 "%s#%d: can't config space for %s#%d",
2488 ddi_driver_name(dbp->dip),
2489 ddi_get_instance(dbp->dip),
2490 ddi_driver_name(dip),
2491 ddi_get_instance(dip));
2492 continue;
2493 }
2494
2495 statep->dip = dip;
2496 statep->command =
2497 pci_config_get16(config_handle, PCI_CONF_COMM);
2498 statep->header_type =
2499 pci_config_get8(config_handle, PCI_CONF_HEADER);
2500 if ((statep->header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE)
2501 statep->bridge_control =
2502 pci_config_get16(config_handle, PCI_BCNF_BCNTRL);
2503 statep->cache_line_size =
2504 pci_config_get8(config_handle, PCI_CONF_CACHE_LINESZ);
2505 statep->latency_timer =
2506 pci_config_get8(config_handle, PCI_CONF_LATENCY_TIMER);
2507 if ((statep->header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE)
2508 statep->sec_latency_timer =
2509 pci_config_get8(config_handle,
2510 PCI_BCNF_LATENCY_TIMER);
2511 pci_config_teardown(&config_handle);
2512 statep++;
2513 }
2514 return (DDI_SUCCESS);
2515 }
2516
2517
2518 /*
2519 * db_restore_config_regs
2520 *
2521 * This routine restores the state of the configuration registers of
2522 * all immediate child nodes.
2523 *
2524 * used by: db_attach() on resume
2525 *
2526 * return value: none
2527 */
2528 static int
db_restore_config_regs(db_ctrl_t * dbp)2529 db_restore_config_regs(db_ctrl_t *dbp)
2530 {
2531 int i;
2532 dev_info_t *dip;
2533 ddi_acc_handle_t config_handle;
2534 db_cfg_state_t *statep = dbp->db_config_state_p;
2535
2536 for (i = 0; i < dbp->config_state_index; i++, statep++) {
2537 dip = statep->dip;
2538 if (!dip) {
2539 cmn_err(CE_WARN,
2540 "%s#%d: skipping bad dev info (index %d)",
2541 ddi_driver_name(dbp->dip),
2542 ddi_get_instance(dbp->dip), i);
2543 continue;
2544 }
2545 if (pci_config_setup(dip, &config_handle) != DDI_SUCCESS) {
2546 cmn_err(CE_WARN,
2547 "%s#%d: can't config space for %s#%d",
2548 ddi_driver_name(dbp->dip),
2549 ddi_get_instance(dbp->dip),
2550 ddi_driver_name(dip),
2551 ddi_get_instance(dip));
2552 continue;
2553 }
2554 pci_config_put16(config_handle, PCI_CONF_COMM, statep->command);
2555 if ((statep->header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE)
2556 pci_config_put16(config_handle, PCI_BCNF_BCNTRL,
2557 statep->bridge_control);
2558 pci_config_put8(config_handle, PCI_CONF_CACHE_LINESZ,
2559 statep->cache_line_size);
2560 pci_config_put8(config_handle, PCI_CONF_LATENCY_TIMER,
2561 statep->latency_timer);
2562 if ((statep->header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE)
2563 pci_config_put8(config_handle, PCI_BCNF_LATENCY_TIMER,
2564 statep->sec_latency_timer);
2565 pci_config_teardown(&config_handle);
2566 }
2567
2568 kmem_free(dbp->db_config_state_p,
2569 dbp->config_state_index * sizeof (db_cfg_state_t));
2570 dbp->db_config_state_p = NULL;
2571 dbp->config_state_index = 0;
2572
2573 return (DDI_SUCCESS);
2574 }
2575
2576 /* put a type 0/1 address on the bus */
2577 static void
db_put_reg_conf_addr(db_acc_pvt_t * db_pvt,uint32_t conf_addr)2578 db_put_reg_conf_addr(db_acc_pvt_t *db_pvt, uint32_t conf_addr)
2579 {
2580 if (db_pvt->access_mode & DB_PCI_CONF_CYCLE_TYPE0)\
2581 ddi_put32(db_pvt->handle, db_pvt->addr, (uint32_t)\
2582 DB_PCI_CONF_CYCLE_TYPE0_ADDR((conf_addr)));\
2583 else /* type 1 cycle */\
2584 ddi_put32(db_pvt->handle, db_pvt->addr, (uint32_t)\
2585 DB_PCI_CONF_CYCLE_TYPE1_ADDR((conf_addr)));
2586 }
2587
2588 /* Get 8bits data off the 32bit data */
2589 static uint8_t
db_get_data8(uint32_t addr,uint32_t data)2590 db_get_data8(uint32_t addr, uint32_t data)
2591 {
2592 return (((data) >> (((addr) & 3) * 8)) & 0xff);
2593 }
2594
2595 /* Get 16bits data off the 32bit data */
2596 static uint16_t
db_get_data16(uint32_t addr,uint32_t data)2597 db_get_data16(uint32_t addr, uint32_t data)
2598 {
2599 return (((data) >> (((addr) & 3) * 8)) & 0xffff);
2600 }
2601
2602 /* merge 8bit data into the 32bit data */
2603 static uint32_t
db_put_data8(uint32_t addr,uint32_t rdata,uint8_t wdata)2604 db_put_data8(uint32_t addr, uint32_t rdata, uint8_t wdata)
2605 {
2606 return ((rdata & (~((0xff << ((((addr) & 3) * 8))) & 0xffffffff))) |
2607 (((wdata) & 0xff)<<((((addr) & 3))*8)));
2608 }
2609
2610 /* merge 16bit data into the 32bit data */
2611 static uint32_t
db_put_data16(uint32_t addr,uint32_t rdata,uint16_t wdata)2612 db_put_data16(uint32_t addr, uint32_t rdata, uint16_t wdata)
2613 {
2614 return ((rdata & (~((0xffff << ((((addr) & 3) * 8))) & 0xffffffff))) |
2615 (((wdata) & 0xffff) << ((((addr) & 3))*8)));
2616 }
2617
2618
2619 /*
2620 * For the next set of PCI configuration IO calls, we need
2621 * to make sure we own the bus before generating the config cycles,
2622 * using the drawbridge's semaphore method.
2623 */
2624
2625 /*
2626 * Function to read 8 bit data off the PCI configuration space behind
2627 * the 21554's host interface.
2628 */
2629 static uint8_t
db_ddi_get8(ddi_acc_impl_t * handle,uint8_t * addr)2630 db_ddi_get8(ddi_acc_impl_t *handle, uint8_t *addr)
2631 {
2632 uint32_t data;
2633
2634 data = db_ddi_get32(handle, (uint32_t *)addr);
2635 return (db_get_data8((uint32_t)(uintptr_t)addr, data));
2636 }
2637
2638 /*
2639 * Function to read 16 bit data off the PCI configuration space behind
2640 * the 21554's host interface.
2641 */
2642 static uint16_t
db_ddi_get16(ddi_acc_impl_t * handle,uint16_t * addr)2643 db_ddi_get16(ddi_acc_impl_t *handle, uint16_t *addr)
2644 {
2645 uint32_t data;
2646
2647 data = db_ddi_get32(handle, (uint32_t *)addr);
2648 return (db_get_data16((uint32_t)(uintptr_t)addr, data));
2649 }
2650
2651 /*
2652 * Function to read 32 bit data off the PCI configuration space behind
2653 * the 21554's host interface.
2654 */
2655 static uint32_t
db_ddi_get32(ddi_acc_impl_t * handle,uint32_t * addr)2656 db_ddi_get32(ddi_acc_impl_t *handle, uint32_t *addr)
2657 {
2658 db_acc_pvt_t *db_pvt = (db_acc_pvt_t *)
2659 handle->ahi_common.ah_bus_private;
2660 uint32_t wait_count = 0;
2661 uint32_t data;
2662 db_ctrl_t *dbp;
2663
2664 dbp = db_pvt->dbp;
2665
2666 mutex_enter(&dbp->db_busown);
2667
2668 if (db_use_config_own_bit) {
2669 /*
2670 * check if (upstream/downstream)configuration address own
2671 * bit set. With this set, we cannot proceed.
2672 */
2673 while (((ddi_get8(db_pvt->handle, db_pvt->bus_own)) &
2674 db_pvt->mask) == db_pvt->mask) {
2675 #ifdef DEBUG
2676 if (dbp->db_pci_max_wait_count < wait_count)
2677 dbp->db_pci_max_wait_count = wait_count;
2678 #endif
2679 drv_usecwait(db_pci_own_wait);
2680 if (++wait_count == db_pci_max_wait) {
2681 /*
2682 * the man page for pci_config_* routines do
2683 * Not specify any error condition values.
2684 */
2685 cmn_err(CE_WARN,
2686 "%s#%d: pci config bus own error",
2687 ddi_driver_name(dbp->dip),
2688 ddi_get_instance(dbp->dip));
2689 dbp->db_pci_err_count++;
2690 mutex_exit(&dbp->db_busown);
2691 return ((uint32_t)DB_CONF_FAILURE);
2692 }
2693 }
2694 wait_count = 0;
2695 }
2696
2697 db_put_reg_conf_addr(db_pvt, (uint32_t)(uintptr_t)addr);
2698 data = ddi_get32(db_pvt->handle, (uint32_t *)db_pvt->data);
2699
2700 if (db_use_config_own_bit) {
2701 while (((ddi_get8(db_pvt->handle, db_pvt->bus_release)) &
2702 db_pvt->mask) == db_pvt->mask) {
2703 #ifdef DEBUG
2704 if (dbp->db_pci_max_wait_count < wait_count)
2705 dbp->db_pci_max_wait_count = wait_count;
2706 #endif
2707 drv_usecwait(db_pci_release_wait);
2708 if (++wait_count == db_pci_max_wait) {
2709 /*
2710 * the man page for pci_config_* routines do
2711 * not specify any error condition values.
2712 */
2713 cmn_err(CE_WARN,
2714 "%s#%d: pci config bus release error",
2715 ddi_driver_name(dbp->dip),
2716 ddi_get_instance(dbp->dip));
2717 dbp->db_pci_err_count++;
2718 mutex_exit(&dbp->db_busown);
2719 return ((uint32_t)DB_CONF_FAILURE);
2720 }
2721 data = ddi_get32(db_pvt->handle,
2722 (uint32_t *)db_pvt->data);
2723 }
2724 }
2725
2726 mutex_exit(&dbp->db_busown);
2727
2728 return (data);
2729 }
2730
2731 /*
2732 * Function to read 64 bit data off the PCI configuration space behind
2733 * the 21554's host interface.
2734 */
2735 static uint64_t
db_ddi_get64(ddi_acc_impl_t * handle,uint64_t * addr)2736 db_ddi_get64(ddi_acc_impl_t *handle, uint64_t *addr)
2737 {
2738 uint64_t udata, ldata;
2739
2740 ldata = (uint32_t)db_ddi_get32(handle, (uint32_t *)addr);
2741 udata = (uint32_t)db_ddi_get32(handle, (uint32_t *)addr + 1);
2742 return (ldata | (udata << 32));
2743 }
2744
2745 /*
2746 * Function to write 8 bit data into the PCI configuration space behind
2747 * the 21554's host interface.
2748 */
2749 static void
db_ddi_put8(ddi_acc_impl_t * handle,uint8_t * addr,uint8_t data)2750 db_ddi_put8(ddi_acc_impl_t *handle, uint8_t *addr, uint8_t data)
2751 {
2752 uint32_t rdata;
2753
2754 rdata = db_ddi_get32(handle, (uint32_t *)addr);
2755 db_ddi_put32(handle, (uint32_t *)addr,
2756 db_put_data8((uint32_t)(uintptr_t)addr, rdata, data));
2757 }
2758
2759 /*
2760 * Function to write 16 bit data into the PCI configuration space behind
2761 * the 21554's host interface.
2762 */
2763 static void
db_ddi_put16(ddi_acc_impl_t * handle,uint16_t * addr,uint16_t data)2764 db_ddi_put16(ddi_acc_impl_t *handle, uint16_t *addr, uint16_t data)
2765 {
2766 uint32_t rdata;
2767
2768 rdata = db_ddi_get32(handle, (uint32_t *)addr);
2769 db_ddi_put32(handle, (uint32_t *)addr,
2770 db_put_data16((uint32_t)(uintptr_t)addr, rdata, data));
2771 }
2772
2773 /*
2774 * Function to write 32 bit data into the PCI configuration space behind
2775 * the 21554's host interface.
2776 */
2777 static void
db_ddi_put32(ddi_acc_impl_t * handle,uint32_t * addr,uint32_t data)2778 db_ddi_put32(ddi_acc_impl_t *handle, uint32_t *addr, uint32_t data)
2779 {
2780 db_acc_pvt_t *db_pvt = (db_acc_pvt_t *)
2781 handle->ahi_common.ah_bus_private;
2782 db_ctrl_t *dbp;
2783 uint32_t wait_count = 0;
2784
2785 dbp = db_pvt->dbp;
2786
2787 mutex_enter(&dbp->db_busown);
2788
2789 if (db_use_config_own_bit) {
2790 /*
2791 * check if (upstream/downstream)configuration address own
2792 * bit set. with this set, we cannot proceed.
2793 */
2794 while (((ddi_get8(db_pvt->handle, db_pvt->bus_own)) &
2795 db_pvt->mask) == db_pvt->mask) {
2796 #ifdef DEBUG
2797 if (dbp->db_pci_max_wait_count < wait_count)
2798 dbp->db_pci_max_wait_count = wait_count;
2799 #endif
2800 drv_usecwait(db_pci_own_wait);
2801 if (++wait_count == db_pci_max_wait) {
2802 /*
2803 * Since the return value is void here,
2804 * we may need to print a message, as this
2805 * could be a serious situation.
2806 */
2807 cmn_err(CE_WARN,
2808 "%s#%d: pci config bus own error",
2809 ddi_driver_name(dbp->dip),
2810 ddi_get_instance(dbp->dip));
2811 dbp->db_pci_err_count++;
2812 mutex_exit(&dbp->db_busown);
2813 return;
2814 }
2815 }
2816 wait_count = 0;
2817 }
2818
2819 db_put_reg_conf_addr(db_pvt, (uint32_t)(uintptr_t)addr);
2820 ddi_put32(db_pvt->handle, (uint32_t *)db_pvt->data, data);
2821
2822 if (db_use_config_own_bit) {
2823 while (((ddi_get8(db_pvt->handle, db_pvt->bus_release)) &
2824 db_pvt->mask) == db_pvt->mask) {
2825 #ifdef DEBUG
2826 if (dbp->db_pci_max_wait_count < wait_count)
2827 dbp->db_pci_max_wait_count = wait_count;
2828 #endif
2829 drv_usecwait(db_pci_release_wait);
2830 if (++wait_count == db_pci_max_wait) {
2831 /*
2832 * the man page for pci_config_* routines do
2833 * Not specify any error condition values.
2834 */
2835 cmn_err(CE_WARN,
2836 "%s#%d: pci config bus release error",
2837 ddi_driver_name(dbp->dip),
2838 ddi_get_instance(dbp->dip));
2839 dbp->db_pci_err_count++;
2840 mutex_exit(&dbp->db_busown);
2841 return;
2842 }
2843 ddi_put32(db_pvt->handle, (uint32_t *)db_pvt->data,
2844 data);
2845 }
2846 }
2847
2848 mutex_exit(&dbp->db_busown);
2849 }
2850
2851 /*
2852 * Function to write 64 bit data into the PCI configuration space behind
2853 * the 21554's host interface.
2854 */
2855 static void
db_ddi_put64(ddi_acc_impl_t * handle,uint64_t * addr,uint64_t data)2856 db_ddi_put64(ddi_acc_impl_t *handle, uint64_t *addr, uint64_t data)
2857 {
2858 db_ddi_put32(handle, (uint32_t *)addr, (uint32_t)(data & 0xffffffff));
2859 db_ddi_put32(handle, (uint32_t *)addr + 1, (uint32_t)(data >> 32));
2860 }
2861
2862 /*
2863 * Function to rep read 8 bit data off the PCI configuration space behind
2864 * the 21554's host interface.
2865 */
2866 static void
db_ddi_rep_get8(ddi_acc_impl_t * handle,uint8_t * host_addr,uint8_t * dev_addr,size_t repcount,uint_t flags)2867 db_ddi_rep_get8(ddi_acc_impl_t *handle, uint8_t *host_addr,
2868 uint8_t *dev_addr, size_t repcount, uint_t flags)
2869 {
2870 if (flags == DDI_DEV_AUTOINCR)
2871 for (; repcount; repcount--)
2872 *host_addr++ = db_ddi_get8(handle, dev_addr++);
2873 else
2874 for (; repcount; repcount--)
2875 *host_addr++ = db_ddi_get8(handle, dev_addr);
2876 }
2877
2878 /*
2879 * Function to rep read 16 bit data off the PCI configuration space behind
2880 * the 21554's host interface.
2881 */
2882 static void
db_ddi_rep_get16(ddi_acc_impl_t * handle,uint16_t * host_addr,uint16_t * dev_addr,size_t repcount,uint_t flags)2883 db_ddi_rep_get16(ddi_acc_impl_t *handle, uint16_t *host_addr,
2884 uint16_t *dev_addr, size_t repcount, uint_t flags)
2885 {
2886 if (flags == DDI_DEV_AUTOINCR)
2887 for (; repcount; repcount--)
2888 *host_addr++ = db_ddi_get16(handle, dev_addr++);
2889 else
2890 for (; repcount; repcount--)
2891 *host_addr++ = db_ddi_get16(handle, dev_addr);
2892 }
2893
2894 /*
2895 * Function to rep read 32 bit data off the PCI configuration space behind
2896 * the 21554's host interface.
2897 */
2898 static void
db_ddi_rep_get32(ddi_acc_impl_t * handle,uint32_t * host_addr,uint32_t * dev_addr,size_t repcount,uint_t flags)2899 db_ddi_rep_get32(ddi_acc_impl_t *handle, uint32_t *host_addr,
2900 uint32_t *dev_addr, size_t repcount, uint_t flags)
2901 {
2902 if (flags == DDI_DEV_AUTOINCR)
2903 for (; repcount; repcount--)
2904 *host_addr++ = db_ddi_get32(handle, dev_addr++);
2905 else
2906 for (; repcount; repcount--)
2907 *host_addr++ = db_ddi_get32(handle, dev_addr);
2908 }
2909
2910 /*
2911 * Function to rep read 64 bit data off the PCI configuration space behind
2912 * the 21554's host interface.
2913 */
2914 static void
db_ddi_rep_get64(ddi_acc_impl_t * handle,uint64_t * host_addr,uint64_t * dev_addr,size_t repcount,uint_t flags)2915 db_ddi_rep_get64(ddi_acc_impl_t *handle, uint64_t *host_addr,
2916 uint64_t *dev_addr, size_t repcount, uint_t flags)
2917 {
2918 if (flags == DDI_DEV_AUTOINCR)
2919 for (; repcount; repcount--)
2920 *host_addr++ = db_ddi_get64(handle, dev_addr++);
2921 else
2922 for (; repcount; repcount--)
2923 *host_addr++ = db_ddi_get64(handle, dev_addr);
2924 }
2925
2926 /*
2927 * Function to rep write 8 bit data into the PCI configuration space behind
2928 * the 21554's host interface.
2929 */
2930 static void
db_ddi_rep_put8(ddi_acc_impl_t * handle,uint8_t * host_addr,uint8_t * dev_addr,size_t repcount,uint_t flags)2931 db_ddi_rep_put8(ddi_acc_impl_t *handle, uint8_t *host_addr,
2932 uint8_t *dev_addr, size_t repcount, uint_t flags)
2933 {
2934 if (flags == DDI_DEV_AUTOINCR)
2935 for (; repcount; repcount--)
2936 db_ddi_put8(handle, dev_addr++, *host_addr++);
2937 else
2938 for (; repcount; repcount--)
2939 db_ddi_put8(handle, dev_addr, *host_addr++);
2940 }
2941
2942 /*
2943 * Function to rep write 16 bit data into the PCI configuration space behind
2944 * the 21554's host interface.
2945 */
2946 static void
db_ddi_rep_put16(ddi_acc_impl_t * handle,uint16_t * host_addr,uint16_t * dev_addr,size_t repcount,uint_t flags)2947 db_ddi_rep_put16(ddi_acc_impl_t *handle, uint16_t *host_addr,
2948 uint16_t *dev_addr, size_t repcount, uint_t flags)
2949 {
2950 if (flags == DDI_DEV_AUTOINCR)
2951 for (; repcount; repcount--)
2952 db_ddi_put16(handle, dev_addr++, *host_addr++);
2953 else
2954 for (; repcount; repcount--)
2955 db_ddi_put16(handle, dev_addr, *host_addr++);
2956 }
2957
2958 /*
2959 * Function to rep write 32 bit data into the PCI configuration space behind
2960 * the 21554's host interface.
2961 */
2962 static void
db_ddi_rep_put32(ddi_acc_impl_t * handle,uint32_t * host_addr,uint32_t * dev_addr,size_t repcount,uint_t flags)2963 db_ddi_rep_put32(ddi_acc_impl_t *handle, uint32_t *host_addr,
2964 uint32_t *dev_addr, size_t repcount, uint_t flags)
2965 {
2966 if (flags == DDI_DEV_AUTOINCR)
2967 for (; repcount; repcount--)
2968 db_ddi_put32(handle, dev_addr++, *host_addr++);
2969 else
2970 for (; repcount; repcount--)
2971 db_ddi_put32(handle, dev_addr, *host_addr++);
2972 }
2973
2974 /*
2975 * Function to rep write 64 bit data into the PCI configuration space behind
2976 * the 21554's host interface.
2977 */
2978 static void
db_ddi_rep_put64(ddi_acc_impl_t * handle,uint64_t * host_addr,uint64_t * dev_addr,size_t repcount,uint_t flags)2979 db_ddi_rep_put64(ddi_acc_impl_t *handle, uint64_t *host_addr,
2980 uint64_t *dev_addr, size_t repcount, uint_t flags)
2981 {
2982 if (flags == DDI_DEV_AUTOINCR)
2983 for (; repcount; repcount--)
2984 db_ddi_put64(handle, dev_addr++, *host_addr++);
2985 else
2986 for (; repcount; repcount--)
2987 db_ddi_put64(handle, dev_addr, *host_addr++);
2988 }
2989
2990 #ifdef DEBUG
2991
2992 static void
db_debug(uint64_t func_id,dev_info_t * dip,char * fmt,uintptr_t a1,uintptr_t a2,uintptr_t a3,uintptr_t a4,uintptr_t a5)2993 db_debug(uint64_t func_id, dev_info_t *dip, char *fmt,
2994 uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5)
2995 {
2996 char *s = NULL;
2997 uint_t dip_no_disp = 0;
2998
2999 if (func_id & DB_DONT_DISPLAY_DIP) {
3000 dip_no_disp = 1;
3001 }
3002 if (db_debug_funcs & func_id) {
3003 switch (func_id) {
3004 case DB_INIT: s = "_init"; break;
3005 case DB_FINI: s = "_fini"; break;
3006 case DB_INFO: s = "_info"; break;
3007 case DB_GETINFO: s = "getinfo"; break;
3008 case DB_ATTACH: s = "attach"; break;
3009 case DB_DETACH: s = "detach"; break;
3010 case DB_CTLOPS: s = "ctlops"; break;
3011 case DB_INITCHILD: s = "initchild"; break;
3012 case DB_REMOVECHILD: s = "removechild"; break;
3013 case DB_INTR_OPS: s = "intr_ops"; break;
3014 case DB_PCI_MAP: s = "map"; break;
3015 case DB_SAVE_CONF_REGS: s = "save_conf_regs"; break;
3016 case DB_REST_CONF_REGS: s = "restore_conf_regs"; break;
3017 case DB_INTR: s = "intr"; break;
3018 case DB_OPEN: s = "open"; break;
3019 case DB_CLOSE: s = "close"; break;
3020 case DB_IOCTL: s = "ioctl"; break;
3021 case DB_DVMA: s = "set_dvma_range"; break;
3022
3023 default: s = "PCI debug unknown"; break;
3024 }
3025
3026 if (s && !dip_no_disp) {
3027 prom_printf("%s(%d): %s: ", ddi_driver_name(dip),
3028 ddi_get_instance(dip), s);
3029 }
3030 prom_printf(fmt, a1, a2, a3, a4, a5);
3031 }
3032 }
3033 #endif
3034
db_prop_op(dev_t dev,dev_info_t * dip,ddi_prop_op_t prop_op,int flags,char * name,caddr_t valuep,int * lengthp)3035 static int db_prop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op,
3036 int flags, char *name, caddr_t valuep, int *lengthp)
3037 {
3038 minor_t minor = getminor(dev);
3039 int instance = PCIHP_AP_MINOR_NUM_TO_INSTANCE(minor);
3040
3041 db_ctrl_t *dbp = (db_ctrl_t *)ddi_get_soft_state(db_state, instance);
3042
3043
3044 if (dbp == NULL)
3045 return (ENXIO);
3046
3047 if (dbp->dev_state & DB_SECONDARY_NEXUS)
3048 return ((pcihp_get_cb_ops())->cb_prop_op(dev, dip,
3049 prop_op, flags, name, valuep, lengthp));
3050
3051 return (ddi_prop_op(dev, dip, prop_op, flags, name, valuep, lengthp));
3052 }
3053
3054 /*
3055 * Initialize our FMA resources
3056 */
3057 static void
db_fm_init(db_ctrl_t * db_p)3058 db_fm_init(db_ctrl_t *db_p)
3059 {
3060 db_p->fm_cap = DDI_FM_EREPORT_CAPABLE | DDI_FM_ERRCB_CAPABLE |
3061 DDI_FM_ACCCHK_CAPABLE | DDI_FM_DMACHK_CAPABLE;
3062
3063 /*
3064 * Request our capability level and get our parents capability
3065 * and ibc.
3066 */
3067 ddi_fm_init(db_p->dip, &db_p->fm_cap, &db_p->fm_ibc);
3068 ASSERT((db_p->fm_cap & DDI_FM_EREPORT_CAPABLE) &&
3069 (db_p->fm_cap & DDI_FM_ERRCB_CAPABLE));
3070
3071 pci_ereport_setup(db_p->dip);
3072
3073 /*
3074 * Register error callback with our parent.
3075 */
3076 ddi_fm_handler_register(db_p->dip, db_err_callback, NULL);
3077 }
3078
3079 /*
3080 * Breakdown our FMA resources
3081 */
3082 static void
db_fm_fini(db_ctrl_t * db_p)3083 db_fm_fini(db_ctrl_t *db_p)
3084 {
3085 /*
3086 * Clean up allocated fm structures
3087 */
3088 ddi_fm_handler_unregister(db_p->dip);
3089 pci_ereport_teardown(db_p->dip);
3090 ddi_fm_fini(db_p->dip);
3091 }
3092
3093 /*
3094 * Initialize FMA resources for children devices. Called when
3095 * child calls ddi_fm_init().
3096 */
3097 /*ARGSUSED*/
3098 static int
db_fm_init_child(dev_info_t * dip,dev_info_t * tdip,int cap,ddi_iblock_cookie_t * ibc)3099 db_fm_init_child(dev_info_t *dip, dev_info_t *tdip, int cap,
3100 ddi_iblock_cookie_t *ibc)
3101 {
3102 db_ctrl_t *db_p = (db_ctrl_t *)ddi_get_soft_state(db_state,
3103 ddi_get_instance(dip));
3104 *ibc = db_p->fm_ibc;
3105 return (db_p->fm_cap);
3106 }
3107
3108 /*
3109 * FMA registered error callback
3110 */
3111 static int
db_err_callback(dev_info_t * dip,ddi_fm_error_t * derr,const void * impl_data)3112 db_err_callback(dev_info_t *dip, ddi_fm_error_t *derr, const void *impl_data)
3113 {
3114 ASSERT(impl_data == NULL);
3115 pci_ereport_post(dip, derr, NULL);
3116 return (derr->fme_status);
3117 }
3118
3119 static void
db_bus_enter(dev_info_t * dip,ddi_acc_handle_t handle)3120 db_bus_enter(dev_info_t *dip, ddi_acc_handle_t handle)
3121 {
3122 i_ndi_busop_access_enter(dip, handle);
3123 }
3124
3125 /* ARGSUSED */
3126 static void
db_bus_exit(dev_info_t * dip,ddi_acc_handle_t handle)3127 db_bus_exit(dev_info_t *dip, ddi_acc_handle_t handle)
3128 {
3129 i_ndi_busop_access_exit(dip, handle);
3130 }
3131