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.
9 #include "VirtioSCSIPrivate.h"
16 /*! Copy data between ccb data and buffer
17 ccb - ccb to copy data from/to
18 offset - offset of data in ccb
19 allocation_length- limit of ccb's data buffer according to CDB
20 buffer - data to copy data from/to
21 size - number of bytes to copy
22 to_buffer - true: copy from ccb to buffer
23 false: copy from buffer to ccb
24 return: true, if data of ccb was large enough
27 copy_sg_data(scsi_ccb
*ccb
, uint offset
, uint allocationLength
,
28 void *buffer
, int size
, bool toBuffer
)
30 const physical_entry
*sgList
= ccb
->sg_list
;
31 int sgCount
= ccb
->sg_count
;
33 // skip unused S/G entries
34 while (sgCount
> 0 && offset
>= sgList
->size
) {
35 offset
-= sgList
->size
;
43 // remaining bytes we are allowed to copy from/to ccb
44 int requestSize
= MIN(allocationLength
, ccb
->data_length
) - offset
;
46 // copy one S/G entry at a time
47 for (; size
> 0 && requestSize
> 0 && sgCount
> 0; ++sgList
, --sgCount
) {
50 bytes
= MIN(size
, requestSize
);
51 bytes
= MIN(bytes
, sgList
->size
);
54 vm_memcpy_from_physical(buffer
, sgList
->address
+ offset
, bytes
,
57 vm_memcpy_to_physical(sgList
->address
+ offset
, buffer
, bytes
,
61 buffer
= (char *)buffer
+ bytes
;
71 swap_words(void *data
, size_t size
)
73 uint16
*word
= (uint16
*)data
;
74 size_t count
= size
/ 2;
76 *word
= B_BENDIAN_TO_HOST_INT16(*word
);