1 /* *********************************************************************
2 * Broadcom Common Firmware Environment (CFE)
4 * Device Attach routines File: cfe_attach.c
6 * This module manages the list of device drivers. When a driver
7 * is probed, it can call cfe_attach to create actual device
8 * instances. The routines in this module manage the
9 * device list and the assignment of device names.
11 * Author: Mitch Lichtenberg (mpl@broadcom.com)
13 *********************************************************************
15 * Copyright 2000,2001,2002,2003
16 * Broadcom Corporation. All rights reserved.
18 * This software is furnished under license and may be used and
19 * copied only in accordance with the following terms and
20 * conditions. Subject to these conditions, you may download,
21 * copy, install, use, modify and distribute modified or unmodified
22 * copies of this software in source and/or binary form. No title
23 * or ownership is transferred hereby.
25 * 1) Any source code used, modified or distributed must reproduce
26 * and retain this copyright notice and list of conditions
27 * as they appear in the source file.
29 * 2) No right is granted to use any trade name, trademark, or
30 * logo of Broadcom Corporation. The "Broadcom Corporation"
31 * name may not be used to endorse or promote products derived
32 * from this software without the prior written permission of
33 * Broadcom Corporation.
35 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
36 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
37 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
38 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
39 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
40 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
41 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
42 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
43 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
44 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
45 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
46 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
47 * THE POSSIBILITY OF SUCH DAMAGE.
48 ********************************************************************* */
51 #include "lib_types.h"
52 #include "lib_malloc.h"
53 #include "lib_queue.h"
54 #include "lib_printf.h"
55 #include "lib_string.h"
57 #include "cfe_device.h"
59 /* *********************************************************************
61 ********************************************************************* */
63 #define CFE_MAX_DEVINST 64 /* max # of instances of devices */
65 /* *********************************************************************
67 ********************************************************************* */
73 queue_t cfe_devices
= {&cfe_devices
, &cfe_devices
};
75 /* *********************************************************************
78 * Locate a device in the device list by its name and return
79 * a pointer to the device structure.
82 * name - name of device, e.g., "uart0"
85 * cfe_device_t pointer or NULL
86 ********************************************************************* */
88 cfe_device_t
*cfe_finddev(char *name
)
93 for (qb
= cfe_devices
.q_next
; qb
!= &cfe_devices
; qb
= qb
->q_next
) {
94 dev
= (cfe_device_t
*) qb
;
95 if (strcmp(dev
->dev_fullname
,name
) == 0) {
104 /* *********************************************************************
107 * Call all the "reset" methods in the devices on the device
108 * list. Note that the methods get called even when the
109 * devices are closed!
116 ********************************************************************* */
118 void cfe_device_reset(void)
123 for (qb
= cfe_devices
.q_next
; qb
!= &cfe_devices
; qb
= qb
->q_next
) {
124 dev
= (cfe_device_t
*) qb
;
125 if (dev
->dev_dispatch
->dev_reset
) {
126 (*(dev
->dev_dispatch
->dev_reset
))(dev
->dev_softc
);
131 /* *********************************************************************
132 * cfe_attach_idx(drv,idx,softc,bootinfo,description)
134 * Add a device to the device list at a specific index. This
135 * is mainly used for devices like SCSI disks or CD-ROMs so
136 * we can use an index that matches the target ID or LUN.
139 * drv - driver structure (from the device driver module)
140 * idx - requested index (e.g., uartn where 'n' is the idx)
141 * softc - Unique information maintained for this device
142 * bootinfo - suffix for long form of the device name. For
143 * example, scsi0.3.1 might mean SCSI controller
144 * 0, device ID 3, LUN 1. The bootinfo would be
146 * description - something nice to say for the devices command
149 * 0 if device has already been added at this index
150 * <0 for other problems
151 * 1 if we were successful.
152 ********************************************************************* */
154 int cfe_attach_idx(cfe_driver_t
*drv
,int idx
,void *softc
,
155 char *bootinfo
,char *description
)
160 xsprintf(name
,"%s%d",drv
->drv_bootname
,idx
);
164 strcat(name
,bootinfo
);
167 if (cfe_finddev(name
) != NULL
) {
171 dev
= (cfe_device_t
*) KMALLOC(sizeof(cfe_device_t
),0);
174 dev
->dev_fullname
= strdup(name
);
175 dev
->dev_softc
= softc
;
176 dev
->dev_class
= drv
->drv_class
;
177 dev
->dev_dispatch
= drv
->drv_dispatch
;
178 dev
->dev_description
= description
? strdup(description
) : NULL
;
179 dev
->dev_opencount
= 0;
181 q_enqueue(&cfe_devices
,(queue_t
*) dev
);
189 /* *********************************************************************
190 * cfe_attach(drv,softc,bootinfo,description
192 * Add a device to the system. This is a callback from the
193 * probe routine, and is used to actually add devices to CFE's
197 * drv - driver structure (from the device driver module)
198 * softc - Unique information maintained for this device
199 * bootinfo - suffix for long form of the device name. For
200 * example, scsi0.3.1 might mean SCSI controller
201 * 0, device ID 3, LUN 1. The bootinfo would be
203 * description - something nice to say for the devices command
207 ********************************************************************* */
209 void cfe_attach(cfe_driver_t
*drv
,void *softc
,
217 * Try device indicies 0..CFE_MAX_DEVINST to assign a unique
218 * device name for this device. This is a really braindead way to
219 * do this, but how many devices are we expecting anyway?
222 for (idx
= 0; idx
< CFE_MAX_DEVINST
; idx
++) {
224 res
= cfe_attach_idx(drv
,idx
,softc
,bootinfo
,description
);
226 if (res
< 0) break; /* out of memory or other badness */
227 if (res
> 0) break; /* success! */
228 /* otherwise, try again, slot is taken */
233 /* *********************************************************************
236 * Initialize this module.
243 ********************************************************************* */
244 void cfe_attach_init(void)
246 q_init(&(cfe_devices
));
250 /* *********************************************************************
251 * cfe_device_name(ctx)
253 * Given a device context, return a device name
260 ********************************************************************* */
262 char *cfe_device_name(cfe_devctx_t
*ctx
)
264 return ctx
->dev_dev
->dev_fullname
;