Rev 3531 | Rev 3538 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 3531 | Rev 3537 | ||
|---|---|---|---|
| Line 80... | Line 80... | ||
| 80 | futex_up(&dcl_lock); |
80 | futex_up(&dcl_lock); |
| 81 | return NULL; |
81 | return NULL; |
| 82 | } |
82 | } |
| 83 | 83 | ||
| 84 | static int devcon_add(dev_handle_t dev_handle, int dev_phone, void *com_area, |
84 | static int devcon_add(dev_handle_t dev_handle, int dev_phone, void *com_area, |
| 85 | size_t com_size, void *bb_buf, off_t bb_off, size_t bb_size) |
85 | size_t com_size) |
| 86 | { |
86 | { |
| 87 | link_t *cur; |
87 | link_t *cur; |
| 88 | devcon_t *devcon; |
88 | devcon_t *devcon; |
| 89 | 89 | ||
| 90 | devcon = malloc(sizeof(devcon_t)); |
90 | devcon = malloc(sizeof(devcon_t)); |
| Line 94... | Line 94... | ||
| 94 | link_initialize(&devcon->link); |
94 | link_initialize(&devcon->link); |
| 95 | devcon->dev_handle = dev_handle; |
95 | devcon->dev_handle = dev_handle; |
| 96 | devcon->dev_phone = dev_phone; |
96 | devcon->dev_phone = dev_phone; |
| 97 | devcon->com_area = com_area; |
97 | devcon->com_area = com_area; |
| 98 | devcon->com_size = com_size; |
98 | devcon->com_size = com_size; |
| 99 | devcon->bb_buf = bb_buf; |
99 | devcon->bb_buf = NULL; |
| 100 | devcon->bb_off = bb_off; |
100 | devcon->bb_off = 0; |
| 101 | devcon->bb_size = bb_size; |
101 | devcon->bb_size = 0; |
| 102 | 102 | ||
| 103 | futex_down(&dcl_lock); |
103 | futex_down(&dcl_lock); |
| 104 | for (cur = dcl_head.next; cur != &dcl_head; cur = cur->next) { |
104 | for (cur = dcl_head.next; cur != &dcl_head; cur = cur->next) { |
| 105 | devcon_t *d = list_get_instance(cur, devcon_t, link); |
105 | devcon_t *d = list_get_instance(cur, devcon_t, link); |
| 106 | if (d->dev_handle == dev_handle) { |
106 | if (d->dev_handle == dev_handle) { |
| Line 119... | Line 119... | ||
| 119 | futex_down(&dcl_lock); |
119 | futex_down(&dcl_lock); |
| 120 | list_remove(&devcon->link); |
120 | list_remove(&devcon->link); |
| 121 | futex_up(&dcl_lock); |
121 | futex_up(&dcl_lock); |
| 122 | } |
122 | } |
| 123 | 123 | ||
| 124 | int |
- | |
| 125 | block_init(dev_handle_t dev_handle, size_t com_size, off_t bb_off, |
124 | int block_init(dev_handle_t dev_handle, size_t com_size) |
| 126 | size_t bb_size) |
- | |
| 127 | { |
125 | { |
| 128 | int rc; |
126 | int rc; |
| 129 | int dev_phone; |
127 | int dev_phone; |
| 130 | void *com_area; |
128 | void *com_area; |
| 131 | void *bb_buf; |
- | |
| 132 | - | ||
| 133 | bb_buf = malloc(bb_size); |
- | |
| 134 | if (!bb_buf) |
- | |
| 135 | return ENOMEM; |
- | |
| 136 | 129 | ||
| 137 | com_area = mmap(NULL, com_size, PROTO_READ | PROTO_WRITE, |
130 | com_area = mmap(NULL, com_size, PROTO_READ | PROTO_WRITE, |
| 138 | MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); |
131 | MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); |
| 139 | if (!com_area) { |
132 | if (!com_area) { |
| 140 | free(bb_buf); |
- | |
| 141 | return ENOMEM; |
133 | return ENOMEM; |
| 142 | } |
134 | } |
| 143 | dev_phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP, |
135 | dev_phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP, |
| 144 | DEVMAP_CONNECT_TO_DEVICE, dev_handle); |
136 | DEVMAP_CONNECT_TO_DEVICE, dev_handle); |
| 145 | 137 | ||
| 146 | if (dev_phone < 0) { |
138 | if (dev_phone < 0) { |
| 147 | free(bb_buf); |
- | |
| 148 | munmap(com_area, com_size); |
139 | munmap(com_area, com_size); |
| 149 | return dev_phone; |
140 | return dev_phone; |
| 150 | } |
141 | } |
| 151 | 142 | ||
| 152 | rc = ipc_share_out_start(dev_phone, com_area, |
143 | rc = ipc_share_out_start(dev_phone, com_area, |
| 153 | AS_AREA_READ | AS_AREA_WRITE); |
144 | AS_AREA_READ | AS_AREA_WRITE); |
| 154 | if (rc != EOK) { |
145 | if (rc != EOK) { |
| 155 | free(bb_buf); |
- | |
| 156 | munmap(com_area, com_size); |
146 | munmap(com_area, com_size); |
| 157 | ipc_hangup(dev_phone); |
147 | ipc_hangup(dev_phone); |
| 158 | return rc; |
148 | return rc; |
| 159 | } |
149 | } |
| 160 | 150 | ||
| 161 | rc = devcon_add(dev_handle, dev_phone, com_area, com_size, bb_buf, |
151 | rc = devcon_add(dev_handle, dev_phone, com_area, com_size); |
| 162 | bb_off, bb_size); |
- | |
| 163 | if (rc != EOK) { |
152 | if (rc != EOK) { |
| 164 | free(bb_buf); |
- | |
| 165 | munmap(com_area, com_size); |
153 | munmap(com_area, com_size); |
| 166 | ipc_hangup(dev_phone); |
154 | ipc_hangup(dev_phone); |
| 167 | return rc; |
155 | return rc; |
| 168 | } |
156 | } |
| 169 | 157 | ||
| 170 | off_t bufpos = 0; |
- | |
| 171 | size_t buflen = 0; |
- | |
| 172 | if (!block_read(dev_handle, &bufpos, &buflen, &bb_off, |
- | |
| 173 | bb_buf, bb_size, bb_size)) { |
- | |
| 174 | block_fini(dev_handle); |
- | |
| 175 | return EIO; /* XXX real error code */ |
- | |
| 176 | } |
- | |
| 177 | - | ||
| 178 | return EOK; |
158 | return EOK; |
| 179 | } |
159 | } |
| 180 | 160 | ||
| 181 | void block_fini(dev_handle_t dev_handle) |
161 | void block_fini(dev_handle_t dev_handle) |
| 182 | { |
162 | { |
| 183 | devcon_t *devcon = devcon_search(dev_handle); |
163 | devcon_t *devcon = devcon_search(dev_handle); |
| 184 | assert(devcon); |
164 | assert(devcon); |
| 185 | 165 | ||
| 186 | devcon_remove(devcon); |
166 | devcon_remove(devcon); |
| 187 | 167 | ||
| - | 168 | if (devcon->bb_buf) |
|
| 188 | free(devcon->bb_buf); |
169 | free(devcon->bb_buf); |
| 189 | munmap(devcon->com_area, devcon->com_size); |
170 | munmap(devcon->com_area, devcon->com_size); |
| 190 | ipc_hangup(devcon->dev_phone); |
171 | ipc_hangup(devcon->dev_phone); |
| 191 | 172 | ||
| 192 | free(devcon); |
173 | free(devcon); |
| 193 | } |
174 | } |
| 194 | 175 | ||
| - | 176 | int block_bb_read(dev_handle_t dev_handle, off_t off, size_t size) |
|
| - | 177 | { |
|
| - | 178 | void *bb_buf; |
|
| - | 179 | ||
| - | 180 | devcon_t *devcon = devcon_search(dev_handle); |
|
| - | 181 | if (!devcon) |
|
| - | 182 | return ENOENT; |
|
| - | 183 | if (devcon->bb_buf) |
|
| - | 184 | return EEXIST; |
|
| - | 185 | bb_buf = malloc(size); |
|
| - | 186 | if (!bb_buf) |
|
| - | 187 | return ENOMEM; |
|
| - | 188 | ||
| - | 189 | off_t bufpos = 0; |
|
| - | 190 | size_t buflen = 0; |
|
| - | 191 | if (!block_read(dev_handle, &bufpos, &buflen, &off, |
|
| - | 192 | bb_buf, size, size)) { |
|
| - | 193 | free(bb_buf); |
|
| - | 194 | return EIO; /* XXX real error code */ |
|
| - | 195 | } |
|
| - | 196 | devcon->bb_buf = bb_buf; |
|
| - | 197 | devcon->bb_off = off; |
|
| - | 198 | devcon->bb_size = size; |
|
| - | 199 | ||
| - | 200 | return EOK; |
|
| - | 201 | } |
|
| - | 202 | ||
| 195 | void *block_bb_get(dev_handle_t dev_handle) |
203 | void *block_bb_get(dev_handle_t dev_handle) |
| 196 | { |
204 | { |
| 197 | devcon_t *devcon = devcon_search(dev_handle); |
205 | devcon_t *devcon = devcon_search(dev_handle); |
| 198 | assert(devcon); |
206 | assert(devcon); |
| 199 | return devcon->bb_buf; |
207 | return devcon->bb_buf; |