sprofalyze fixes
[minix.git] / lib / libbdev / minor.c
blob519da33eb75d33eefc201a6a2e4017ed087b70c3
1 /* libbdev - tracking and reopening of opened minor devices */
3 #include <minix/drivers.h>
4 #include <minix/bdev.h>
5 #include <assert.h>
7 #include "const.h"
8 #include "type.h"
9 #include "proto.h"
11 static struct {
12 dev_t dev;
13 int count;
14 int access;
15 } open_dev[NR_OPEN_DEVS] = { { NO_DEV, 0, 0 } };
17 int bdev_minor_reopen(dev_t dev)
19 /* Reopen all minor devices on a major device. This function duplicates some
20 * code from elsewhere, because in this case we must avoid performing recovery.
21 * FIXME: if reopening fails with a non-IPC error, we should attempt to close
22 * all minors that we did manage to reopen so far, or they might stay open
23 * forever.
25 endpoint_t endpt;
26 message m;
27 int i, j, r, major;
29 major = major(dev);
30 endpt = bdev_driver_get(dev);
32 assert(endpt != NONE);
34 for (i = 0; i < NR_OPEN_DEVS; i++) {
35 if (major(open_dev[i].dev) != major)
36 continue;
38 /* Each minor device may have been opened multiple times. Send an open
39 * request for each time that it was opened before. We could reopen it
40 * just once, but then we'd have to keep a shadow open count as well.
42 for (j = 0; j < open_dev[i].count; j++) {
43 memset(&m, 0, sizeof(m));
44 m.m_type = BDEV_OPEN;
45 m.BDEV_MINOR = minor(open_dev[i].dev);
46 m.BDEV_ACCESS = open_dev[i].access;
47 m.BDEV_ID = NO_ID;
49 if ((r = sendrec(endpt, &m)) != OK) {
50 printf("bdev: IPC to driver (%d) failed (%d)\n",
51 endpt, r);
52 return r;
55 if (m.m_type != BDEV_REPLY) {
56 printf("bdev: driver (%d) sent weird response (%d)\n",
57 endpt, m.m_type);
58 return EINVAL;
61 if (m.BDEV_ID != NO_ID) {
62 printf("bdev: driver (%d) sent invalid ID (%ld)\n",
63 endpt, m.BDEV_ID);
64 return EINVAL;
67 if ((r = m.BDEV_STATUS) != OK) {
68 printf("bdev: driver (%d) failed device reopen (%d)\n",
69 endpt, r);
70 return r;
75 return OK;
78 void bdev_minor_add(dev_t dev, int access)
80 /* Increase the reference count of the given minor device.
82 int i, free = -1;
84 for (i = 0; i < NR_OPEN_DEVS; i++) {
85 if (open_dev[i].dev == dev) {
86 open_dev[i].count++;
87 open_dev[i].access |= access;
89 return;
92 if (free < 0 && open_dev[i].dev == NO_DEV)
93 free = i;
96 if (free < 0) {
97 printf("bdev: too many open devices, increase NR_OPEN_DEVS\n");
98 return;
101 open_dev[free].dev = dev;
102 open_dev[free].count = 1;
103 open_dev[free].access = access;
106 void bdev_minor_del(dev_t dev)
108 /* Decrease the reference count of the given minor device, if present.
110 int i;
112 for (i = 0; i < NR_OPEN_DEVS; i++) {
113 if (open_dev[i].dev == dev) {
114 if (!--open_dev[i].count)
115 open_dev[i].dev = NO_DEV;
117 break;