BPicture: Fix archive constructor.
[haiku.git] / src / add-ons / kernel / bus_managers / ata / ATAHelper.cpp
blob4996c846429361205b1bb11df9bec72eeee9c037
1 /*
2 * Copyright 2009, Michael Lotz, mmlr@mlotz.ch.
3 * Copyright 2004-2007, Axel Dörfler, axeld@pinc-software.de.
4 * Copyright 2002/03, Thomas Kurschel. All rights reserved.
6 * Distributed under the terms of the MIT License.
7 */
9 #include "ATAPrivate.h"
11 #include <vm/vm.h>
12 #include <string.h>
15 /*! Copy data between ccb data and buffer
16 ccb - ccb to copy data from/to
17 offset - offset of data in ccb
18 allocation_length- limit of ccb's data buffer according to CDB
19 buffer - data to copy data from/to
20 size - number of bytes to copy
21 to_buffer - true: copy from ccb to buffer
22 false: copy from buffer to ccb
23 return: true, if data of ccb was large enough
25 bool
26 copy_sg_data(scsi_ccb *ccb, uint offset, uint allocationLength,
27 void *buffer, int size, bool toBuffer)
29 const physical_entry *sgList = ccb->sg_list;
30 int sgCount = ccb->sg_count;
32 // skip unused S/G entries
33 while (sgCount > 0 && offset >= sgList->size) {
34 offset -= sgList->size;
35 ++sgList;
36 --sgCount;
39 if (sgCount == 0)
40 return false;
42 // remaining bytes we are allowed to copy from/to ccb
43 int requestSize = MIN(allocationLength, ccb->data_length) - offset;
45 // copy one S/G entry at a time
46 for (; size > 0 && requestSize > 0 && sgCount > 0; ++sgList, --sgCount) {
47 size_t bytes;
49 bytes = MIN(size, requestSize);
50 bytes = MIN(bytes, sgList->size);
52 if (toBuffer) {
53 vm_memcpy_from_physical(buffer, sgList->address + offset, bytes,
54 false);
55 } else {
56 vm_memcpy_to_physical(sgList->address + offset, buffer, bytes,
57 false);
60 buffer = (char *)buffer + bytes;
61 size -= bytes;
62 offset = 0;
65 return size == 0;
69 void
70 swap_words(void *data, size_t size)
72 uint16 *word = (uint16 *)data;
73 size_t count = size / 2;
74 while (count--) {
75 *word = B_BENDIAN_TO_HOST_INT16(*word);
76 word++;