Changeset cbcb34c in mainline for uspace/lib/virtio/virtio-pci.c
- Timestamp:
- 2018-05-22T19:06:50Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 341df5f
- Parents:
- 1c53d93
- git-author:
- Jakub Jermar <jakub@…> (2018-05-05 14:43:51)
- git-committer:
- Jakub Jermar <jakub@…> (2018-05-22 19:06:50)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/virtio/virtio-pci.c
r1c53d93 rcbcb34c 32 32 #include "virtio-pci.h" 33 33 34 #include <as.h> 35 #include <align.h> 36 #include <macros.h> 37 34 38 #include <ddf/driver.h> 35 39 #include <ddf/log.h> … … 173 177 174 178 return EOK; 179 } 180 181 errno_t virtio_virtq_setup(virtio_dev_t *vdev, uint16_t num, uint16_t size, 182 size_t buf_size, uint16_t buf_flags) 183 { 184 virtq_t *q = &vdev->queues[num]; 185 virtio_pci_common_cfg_t *cfg = vdev->common_cfg; 186 187 /* Program the queue of our interest */ 188 pio_write_16(&cfg->queue_select, num); 189 190 /* Trim the size of the queue as needed */ 191 size = min(pio_read_16(&cfg->queue_size), size); 192 pio_write_16(&cfg->queue_size, size); 193 ddf_msg(LVL_NOTE, "Virtq %u: %u buffers", num, (unsigned) size); 194 195 /* Allocate array to hold virtual addresses of DMA buffers */ 196 void **buffers = calloc(sizeof(void *), size); 197 if (!buffers) 198 return ENOMEM; 199 200 size_t avail_offset = 0; 201 size_t used_offset = 0; 202 size_t buffers_offset = 0; 203 204 /* 205 * Compute the size of the needed DMA memory and also the offsets of 206 * the individual components 207 */ 208 size_t mem_size = sizeof(virtq_desc_t[size]); 209 mem_size = ALIGN_UP(mem_size, _Alignof(virtq_avail_t)); 210 avail_offset = mem_size; 211 mem_size += sizeof(virtq_avail_t) + sizeof(ioport16_t[size]) + 212 sizeof(ioport16_t); 213 mem_size = ALIGN_UP(mem_size, _Alignof(virtq_used_t)); 214 used_offset = mem_size; 215 mem_size += sizeof(virtq_used_t) + sizeof(virtq_used_elem_t[size]) + 216 sizeof(ioport16_t); 217 buffers_offset = mem_size; 218 mem_size += size * buf_size; 219 220 /* 221 * Allocate DMA memory for the virtqueues and the buffers 222 */ 223 q->virt = AS_AREA_ANY; 224 errno_t rc = dmamem_map_anonymous(mem_size, DMAMEM_4GiB, 225 AS_AREA_READ | AS_AREA_WRITE, 0, &q->phys, &q->virt); 226 if (rc != EOK) { 227 free(buffers); 228 q->virt = NULL; 229 return rc; 230 } 231 232 q->size = mem_size; 233 q->queue_size = size; 234 q->desc = q->virt; 235 q->avail = q->virt + avail_offset; 236 q->used = q->virt + used_offset; 237 q->buffers = buffers; 238 239 memset(q->virt, 0, q->size); 240 241 /* 242 * Initialize the descriptor table and the buffers array 243 */ 244 for (unsigned i = 0; i < size; i++) { 245 q->desc[i].addr = q->phys + buffers_offset + i * buf_size; 246 q->desc[i].len = buf_size; 247 q->desc[i].flags = buf_flags; 248 249 q->buffers[i] = q->virt + buffers_offset + i * buf_size; 250 } 251 252 /* 253 * Write the configured addresses to device's common config 254 */ 255 pio_write_64(&cfg->queue_desc, q->phys); 256 pio_write_64(&cfg->queue_avail, q->phys + avail_offset); 257 pio_write_64(&cfg->queue_used, q->phys + used_offset); 258 259 ddf_msg(LVL_NOTE, "DMA memory for virtq %d: virt=%p, phys=%p, size=%zu", 260 num, q->virt, (void *) q->phys, q->size); 261 262 return rc; 263 } 264 265 void virtio_virtq_teardown(virtio_dev_t *vdev, uint16_t num) 266 { 267 virtq_t *q = &vdev->queues[num]; 268 if (q->size) 269 dmamem_unmap_anonymous(q->virt); 270 if (q->buffers) 271 free(q->buffers); 175 272 } 176 273 … … 279 376 errno_t virtio_pci_dev_cleanup(virtio_dev_t *vdev) 280 377 { 378 if (vdev->queues) { 379 for (unsigned i = 0; 380 i < pio_read_16(&vdev->common_cfg->num_queues); i++) 381 virtio_virtq_teardown(vdev, i); 382 free(vdev->queues); 383 } 281 384 return disable_resources(vdev); 282 385 }
Note:
See TracChangeset
for help on using the changeset viewer.