Lines Matching refs:buffer

9 	DMA buffer handling.
12 is DMA safe, we check that and copy data to a buffer if needed.
13 The buffer is enlarged on demand and destroyed after a time-out
21 Currently, there is only one buffer per device; in the future,
96 /** copy data from/to DMA buffer */
101 dma_buffer *buffer = request->dma_buffer;
102 const physical_entry *sg_list = buffer->sg_list_orig;
103 uint32 num_vecs = buffer->sg_count_orig;
104 uchar *buffer_data = buffer->address;
111 // we have to use S/G list to original data; the DMA buffer
133 scsi_free_dma_buffer(dma_buffer *buffer)
135 if (buffer->area > 0) {
136 SHOW_FLOW0(1, "Destroying buffer");
138 delete_area(buffer->area);
139 buffer->area = 0;
140 buffer->size = 0;
143 if (buffer->sg_list_area > 0) {
144 delete_area(buffer->sg_list_area);
145 buffer->sg_list_area = 0;
150 /** allocate dma buffer for given device, deleting old one
151 * size - buffer size in bytes
155 scsi_alloc_dma_buffer(dma_buffer *buffer, dma_params *dma_params, uint32 size)
157 // free old buffer first
158 scsi_free_dma_buffer(buffer);
171 // alright - a contiguous buffer is required to keep S/G table short
172 SHOW_INFO(1, "need to setup contiguous DMA buffer of size %" B_PRIu32,
195 buffer->area = create_area_etc(B_SYSTEM_TEAM, "DMA buffer", size,
198 (void**)&buffer->address);
200 if (buffer->area < 0) {
201 SHOW_ERROR(2, "Cannot create contignous DMA buffer of %" B_PRIu32
206 buffer->size = size;
208 // we can live with a fragmented buffer - very nice
209 buffer->area = create_area("DMA buffer",
210 (void **)&buffer->address, B_ANY_KERNEL_ADDRESS, size,
213 if (buffer->area < 0) {
214 SHOW_ERROR(2, "Cannot create DMA buffer of %" B_PRIu32 " bytes",
219 buffer->size = size;
224 size_t sg_list_size = buffer->size / B_PAGE_SIZE * sizeof( physical_entry );
228 buffer->sg_list_area = create_area("DMA buffer S/G table",
229 (void **)&buffer->sg_list, B_ANY_KERNEL_ADDRESS, sg_list_size,
232 if (buffer->sg_list_area < 0) {
233 SHOW_ERROR( 2, "Cannot create DMA buffer S/G list of %" B_PRIuSIZE
236 delete_area(buffer->area);
237 buffer->area = 0;
247 buffer->address,
248 buffer->size
252 &vec, 1, 0, buffer->size,
253 buffer->sg_list, sg_list_entries, &buffer->sg_count,
256 if( res != B_OK || mapped_len != buffer->size ) {
257 SHOW_ERROR(0, "Error creating S/G list for DMA buffer (%s; wanted "
259 mapped_len, buffer->size);
268 scsi_free_dma_buffer_sg_orig(dma_buffer *buffer)
270 if (buffer->sg_orig > 0) {
271 delete_area(buffer->sg_orig);
272 buffer->sg_orig = 0;
273 buffer->sg_count_max_orig = 0;
281 scsi_alloc_dma_buffer_sg_orig(dma_buffer *buffer, size_t size)
284 scsi_free_dma_buffer_sg_orig(buffer);
288 buffer->sg_orig = create_area("S/G to original data",
289 (void **)&buffer->sg_list_orig,
292 if (buffer->sg_orig < 0) {
293 SHOW_ERROR(2, "Cannot S/G list buffer to original data of %" B_PRIuSIZE
298 buffer->sg_count_max_orig = size / sizeof(physical_entry);
301 buffer->sg_count_max_orig);
326 scsi_dma_buffer_compose_sg_orig(dma_buffer *buffer, scsi_ccb *request)
328 // enlarge buffer is required
329 if (buffer->sg_count_max_orig < request->sg_count) {
330 if (!scsi_alloc_dma_buffer_sg_orig(buffer, request->sg_count))
336 memcpy(buffer->sg_list_orig, request->sg_list,
339 buffer->sg_count_orig = request->sg_count;
344 /** init DMA buffer and copy data to it if required
352 dma_buffer *buffer;
364 // only one buffer at a time
370 // there is only one buffer, so no further management
371 buffer = &device->dma_buffer;
373 buffer->inuse = true;
377 // memorize buffer for cleanup
378 request->dma_buffer = buffer;
380 // enlarge buffer if too small
381 if (buffer->size < request->data_length) {
382 if (!scsi_alloc_dma_buffer(buffer, &device->bus->dma_params,
387 // create S/G to original data (necessary for copying from-buffer on end
388 // of request, but also used during copying to-buffer in a second because
392 // copy data to buffer
398 // replace data address, so noone notices that a buffer is used
399 buffer->orig_data = request->data;
400 buffer->orig_sg_list = request->sg_list;
401 buffer->orig_sg_count = request->sg_count;
403 request->data = buffer->address;
404 request->sg_list = buffer->sg_list;
405 request->sg_count = buffer->sg_count;
414 SHOW_INFO0(3, "error setting up DMA buffer");
419 buffer->inuse = false;
428 /*! Copy data back and release DMA buffer;
435 dma_buffer *buffer = request->dma_buffer;
441 // copy data from buffer if required and if operation succeeded
447 request->data = buffer->orig_data;
448 request->sg_list = buffer->orig_sg_list;
449 request->sg_count = buffer->orig_sg_count;
451 // free buffer
454 buffer->last_use = system_time();
455 buffer->inuse = false;
465 /** dameon that deletes DMA buffer if not used for some time */
471 dma_buffer *buffer;
475 buffer = &device->dma_buffer;
477 if (!buffer->inuse
478 && buffer->last_use - system_time() > SCSI_DMA_BUFFER_CLEANUP_DELAY) {
479 scsi_free_dma_buffer(buffer);
480 scsi_free_dma_buffer_sg_orig(buffer);
488 scsi_dma_buffer_free(dma_buffer *buffer)
490 scsi_free_dma_buffer(buffer);
491 scsi_free_dma_buffer_sg_orig(buffer);
496 scsi_dma_buffer_init(dma_buffer *buffer)
498 buffer->area = 0;
499 buffer->size = 0;
500 buffer->sg_orig = 0;
501 buffer->sg_count_max_orig = 0;