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