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; |