1 /* libbdev - driver endpoint management */
3 #include <minix/drivers.h>
4 #include <minix/bdev.h>
14 char label
[DS_MAX_KEYLEN
];
15 } driver_tab
[NR_DEVICES
];
17 void bdev_driver_init(void)
19 /* Initialize the driver table.
23 for (i
= 0; i
< NR_DEVICES
; i
++) {
24 driver_tab
[i
].endpt
= NONE
;
25 driver_tab
[i
].label
[0] = '\0';
29 void bdev_driver_clear(dev_t dev
)
31 /* Clear information about a driver.
37 assert(major
>= 0 && major
< NR_DEVICES
);
39 driver_tab
[major
].endpt
= NONE
;
40 driver_tab
[major
].label
[0] = '\0';
43 endpoint_t
bdev_driver_set(dev_t dev
, char *label
)
45 /* Set the label for a driver, and retrieve the associated endpoint.
51 assert(major
>= 0 && major
< NR_DEVICES
);
52 assert(strlen(label
) < sizeof(driver_tab
[major
].label
));
54 strlcpy(driver_tab
[major
].label
, label
, sizeof(driver_tab
[major
].label
));
56 driver_tab
[major
].endpt
= NONE
;
58 return bdev_driver_update(dev
);
61 endpoint_t
bdev_driver_get(dev_t dev
)
63 /* Return the endpoint for a driver, or NONE if we do not know its endpoint.
69 assert(major
>= 0 && major
< NR_DEVICES
);
71 return driver_tab
[major
].endpt
;
74 endpoint_t
bdev_driver_update(dev_t dev
)
76 /* Update the endpoint of a driver. The caller of this function already knows
77 * that the current endpoint may no longer be valid, and must be updated.
78 * Return the new endpoint upon success, and NONE otherwise.
81 int r
, major
, nr_tries
;
85 assert(major
>= 0 && major
< NR_DEVICES
);
86 assert(driver_tab
[major
].label
[0] != '\0');
88 /* Repeatedly retrieve the endpoint for the driver label, and see if it is a
89 * different, valid endpoint. If retrieval fails at first, we have to wait.
90 * We use polling, as opposed to a DS subscription, for a number of reasons:
91 * 1) DS supports only one subscription per process, and our main program may
92 * already have a subscription;
93 * 2) if we block on receiving a notification from DS, we cannot impose an
94 * upper bound on the retry time;
95 * 3) temporarily subscribing and then unsubscribing may cause leftover DS
96 * notifications, which the main program would then have to deal with.
97 * As of writing, unsubscribing from DS is not possible at all, anyway.
99 * In the normal case, the driver's label/endpoint mapping entry disappears
100 * completely for a short moment, before being replaced with the new mapping.
101 * Hence, failure to retrieve the entry at all does not constitute permanent
102 * failure. In fact, there is no way to determine reliably that a driver has
103 * failed permanently in the current approach. For this we simply rely on the
106 for (nr_tries
= 0; nr_tries
< DS_NR_TRIES
; nr_tries
++) {
107 r
= ds_retrieve_label_endpt(driver_tab
[major
].label
, &endpt
);
109 if (r
== OK
&& endpt
!= NONE
&& endpt
!= driver_tab
[major
].endpt
) {
110 driver_tab
[major
].endpt
= endpt
;
115 if (nr_tries
< DS_NR_TRIES
- 1)
116 micro_delay(DS_DELAY
);
119 driver_tab
[major
].endpt
= NONE
;