/* $Id$ * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. * * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc. * Copyright (C) 2000 by Colin Ngam */ #ifndef _ASM_SN_CDL_H #define _ASM_SN_CDL_H #include /* * cdl: connection/driver list * * support code for bus infrastructure for busses * that have self-identifying devices; initially * constructed for xtalk, pciio and gioio modules. */ typedef struct cdl *cdl_p; /* * cdl_itr_f is the type for the functions * that are handled by cdl_iterate. */ typedef void cdl_iter_f (devfs_handle_t vhdl); /* * cdl_drv_f is the type for the functions * that are called by cdl_add_driver and * cdl_del_driver. */ typedef void cdl_drv_f (devfs_handle_t vhdl, int key1, int key2, int error); /* * If CDL_PRI_HI is specified in the flags * parameter for cdl_add_driver, then that driver's * attach routine will be called for future connect * points before any (non-CDL_PRI_HI) drivers. * * The IOC3 driver uses this facility to make sure * that the ioc3_attach() function is called before * the attach routines of any subdevices. * * Drivers for bridge-based crosstalk cards that * are almost but not quite generic can use it to * arrange that their attach() functions get called * before the generic bridge drivers, so they can * leave behind "hint" structures that will * properly configure the generic driver. */ #define CDL_PRI_HI 0x0001 /* * cdl_new: construct a new connection/driver list * * Called once for each "kind" of bus. Returns an * opaque cookie representing the particular list * that will be operated on by the other calls. */ extern cdl_p cdl_new(char *, char *, char *); /* * cdl_del: destroy a connection/driver list. * * Releases all dynamically allocated resources * associated with the specified list. Forgets what * drivers might be involved in this kind of bus, * forgets what connection points have been noticed * on this kind of bus. */ extern void cdl_del(cdl_p reg); /* * cdl_add_driver: register a device driver * * Calls the driver's attach routine with all * connection points on the list that have the same * key information as the driver; call-back the * specified function to notify the driver of the * attach status for each device. Place the driver * on the list so that any connection points * discovered in the future that match the driver * can be handed off to the driver's attach * routine. * * CDL_PRI_HI may be specified (see above). */ extern int cdl_add_driver(cdl_p reg, int key1, int key2, char *prefix, int flags, cdl_drv_f *func); /* * cdl_del_driver: remove a device driver * * Calls the driver's detach routine with all * connection points on the list that match the * driver; call-back the specified function to * notify the driver of the detach status for each * device. Then forget about the driver. Future * calls to cdl_add_connpt with connections that * would match this driver no longer trigger calls * to the driver's attach routine. * * NOTE: Yes, I said CONNECTION POINTS, not * verticies that the driver has been attached to * with hwgraph_driver_add(); this gives the driver * a chance to clean up anything it did to the * connection point in its attach routine. Also, * this is done whether or not the attach routine * was successful. */ extern void cdl_del_driver(cdl_p reg, char *prefix, cdl_drv_f *func); /* * cdl_add_connpt: add a connection point * * Calls the attach routines of all the drivers on * the list that match this connection point, in * the order that they were added to the list, * except that CDL_PRI_HI drivers are called first. * * Then the vertex is added to the list, so it can * be presented to any matching drivers that may be * subsequently added to the list. */ extern int cdl_add_connpt(cdl_p reg, int key1, int key2, devfs_handle_t conn, int drv_flags); /* * cdl_del_connpt: delete a connection point * * Calls the detach routines of all matching * drivers for this connection point, in the same * order that the attach routines were called; then * forgets about this vertex, so drivers added in * the future will not be told about it. * * NOTE: Same caveat here about the detach calls as * in the cdl_del_driver() comment above. */ extern int cdl_del_connpt(cdl_p reg, int key1, int key2, devfs_handle_t conn, int drv_flags); /* * cdl_iterate: find all verticies in the registry * corresponding to the named driver and call them * with the specified function (giving the vertex * as the parameter). */ extern void cdl_iterate(cdl_p reg, char *prefix, cdl_iter_f *func); /* * An INFO_LBL_ASYNC_ATTACH label is attached to a vertex, pointing to * an instance of async_attach_s to indicate that asynchronous * attachment may be applied to that device ... if the corresponding * driver allows it. */ struct async_attach_s { struct semaphore async_sema; int async_count; }; typedef struct async_attach_s *async_attach_t; async_attach_t async_attach_new(void); void async_attach_free(async_attach_t); async_attach_t async_attach_get_info(devfs_handle_t); void async_attach_add_info(devfs_handle_t, async_attach_t); void async_attach_del_info(devfs_handle_t); void async_attach_signal_start(async_attach_t); void async_attach_signal_done(async_attach_t); void async_attach_waitall(async_attach_t); #endif /* _ASM_SN_CDL_H */