status_t VolumeCryptContext::Setup(int fd, const uint8* key, uint32 keyLength, const uint8* random, uint32 randomLength) { off_t size; status_t status = get_size(fd, size); if (status != B_OK) return status; fOffset = max_c(4096, BLOCK_SIZE); fSize = size - fOffset; fHidden = false; const uint8* salt = random; random += PKCS5_SALT_SIZE; uint8 buffer[BLOCK_SIZE]; memcpy(buffer, salt, PKCS5_SALT_SIZE); memset(buffer + PKCS5_SALT_SIZE, 0, BLOCK_SIZE - PKCS5_SALT_SIZE); true_crypt_header& header = *(true_crypt_header*)&buffer[PKCS5_SALT_SIZE]; header.magic = B_HOST_TO_BENDIAN_INT32(kTrueCryptMagic); header.version = B_HOST_TO_BENDIAN_INT16(0x4); header.required_program_version = B_HOST_TO_BENDIAN_INT16(0x600); header.volume_size = B_HOST_TO_BENDIAN_INT64(fSize); header.encrypted_offset = B_HOST_TO_BENDIAN_INT64(fOffset); header.encrypted_size = B_HOST_TO_BENDIAN_INT64(fSize); header.flags = 0; memcpy(header.disk_key, random, sizeof(header.disk_key)); header.crc_checksum = B_HOST_TO_BENDIAN_INT32(crc32(header.disk_key, 256)); header.header_crc_checksum = B_HOST_TO_BENDIAN_INT32(crc32((uint8*)&header, 188)); return _WriteHeader(fd, key, keyLength, 0, buffer); }
ssize_t QuickCamDevice::ReadIIC16(uint8 address, uint16 *data) { status_t err; uint8 buffer[0x23]; memset(buffer, 0, sizeof(buffer)); buffer[0x20] = Sensor() ? Sensor()->IICReadAddress() : 0; buffer[0x21] = 1 - 1; buffer[0x22] = 0x03; buffer[0] = address; err = SendCommand(USB_REQTYPE_DEVICE_OUT, 0x04, STV_I2C_WRITE, 0, 0x23, buffer); if (err < B_OK) return err; buffer[0] = 0xaa; buffer[1] = 0xaa; err = SendCommand(USB_REQTYPE_DEVICE_IN, 0x04, STV_I2C_READ, 0, 0x2, buffer); PRINT((CH ": SendCommand: %s" CT, strerror(err))); if (err < B_OK) return err; if (fChipIsBigEndian) *data = B_HOST_TO_BENDIAN_INT16(*(uint16 *)(&buffer[0])); else *data = B_HOST_TO_LENDIAN_INT16(*(uint16 *)(&buffer[0])); PRINT((CH ": 0x%04x" CT, *data)); return 2; }
status_t BRawNetBuffer::AppendUint16(uint16 value) { uint16 netVal = B_HOST_TO_BENDIAN_INT16(value); ssize_t sizeW = fBuffer.WriteAt(fWritePosition, &netVal, sizeof(uint16)); if (sizeW == B_NO_MEMORY) return B_NO_MEMORY; fWritePosition += sizeof(uint16); return B_OK; }
void CharView::Draw(BRect urect) { BPoint point; font_height fheight; char utf8Char[3]; uint16 uniChar[1]; urect = Bounds(); // SetLowColor(def_viewcolor); SetDrawingMode(B_OP_COPY); SetHighColor(strokeColor); SetPenSize(1); StrokeRect(urect); urect.InsetBy(1, 1); SetHighColor(bgColor); FillRect(urect); SetLowColor(bgColor); SetHighColor(displayColor); if (drawmode) { font.SetSize(urect.Width() * 0.6); font.GetHeight(&fheight); // Unicode to UTF8 Character encoding uniChar[0] = B_HOST_TO_BENDIAN_INT16(((mutf == 0) || (mutf == 65535)) ? 1 : mutf); int32 state = 0; int32 srcLen = 2; int32 destLen = sizeof(utf8Char); convert_to_utf8(B_UNICODE_CONVERSION, (const char*)uniChar, &srcLen, utf8Char, &destLen, &state); SetFont(&font); bool hasGlyph[1]; font.GetHasGlyphs(utf8Char, 1, hasGlyph); if (hasGlyph[0]) { float choffset = (urect.right - urect.left - StringWidth(utf8Char, destLen)) / 2; float cvoffset = (urect.Height() - fheight.ascent - fheight.descent) / 2 + fheight.ascent; point.Set(choffset, cvoffset); DrawString(utf8Char, destLen, point); } } /* printf("\nCharView!\n"); printf("utf8Char[0]: %x\n", utf8Char[0]); printf("utf8Char[1]: %x\n", utf8Char[1]); printf("utf8Char[2]: %x\n", utf8Char[2]);*/ }
status_t PackageWriter::_Finish() { // write entries for (EntryList::ConstIterator it = fRootEntry->ChildIterator(); Entry* entry = it.Next();) { _AddEntry(AT_FDCWD, entry, entry->Name()); } printf("header size: %lu\n", sizeof(hpkg_header)); printf("heap size: %lld\n", fHeapEnd - sizeof(hpkg_header)); hpkg_header header; // write the TOC and package attributes _WriteTOC(header); _WritePackageAttributes(header); off_t totalSize = fHeapEnd; printf("total size: %lld\n", totalSize); // prepare the header // general header.magic = B_HOST_TO_BENDIAN_INT32(B_HPKG_MAGIC); header.header_size = B_HOST_TO_BENDIAN_INT16( (uint16)sizeof(hpkg_header)); header.version = B_HOST_TO_BENDIAN_INT16(B_HPKG_VERSION); header.total_size = B_HOST_TO_BENDIAN_INT64(totalSize); // write the header _WriteBuffer(&header, sizeof(hpkg_header), 0); fFinished = true; return B_OK; }
static status_t get_position(cd_driver_info *info, scsi_position *position) { scsi_cmd_read_subchannel cmd; TRACE("get_position()\n"); memset(&cmd, 0, sizeof(cmd)); cmd.opcode = SCSI_OP_READ_SUB_CHANNEL; cmd.time = 1; cmd.subq = 1; cmd.parameter_list = scsi_sub_channel_parameter_list_cd_pos; cmd.track = 0; cmd.allocation_length = B_HOST_TO_BENDIAN_INT16(sizeof(scsi_position)); return sSCSIPeripheral->simple_exec(info->scsi_periph_device, &cmd, sizeof(cmd), position, sizeof(*position), SCSI_DIR_IN); }
static status_t read_table_of_contents(int fd, uint32 track, uint8 format, uint8 *buffer, size_t bufferSize) { raw_device_command raw; uint8 *senseData = (uint8 *)malloc(kSenseSize); if (senseData == NULL) return B_NO_MEMORY; memset(&raw, 0, sizeof(raw_device_command)); memset(senseData, 0, kSenseSize); memset(buffer, 0, bufferSize); scsi_cmd_read_toc &toc = *(scsi_cmd_read_toc*)&raw.command; toc.opcode = SCSI_OP_READ_TOC; toc.time = 1; toc.format = format; toc.track = track; toc.allocation_length = B_HOST_TO_BENDIAN_INT16(bufferSize); raw.command_length = 10; raw.flags = B_RAW_DEVICE_DATA_IN | B_RAW_DEVICE_REPORT_RESIDUAL | B_RAW_DEVICE_SHORT_READ_VALID; raw.scsi_status = 0; raw.cam_status = 0; raw.data = buffer; raw.data_length = bufferSize; raw.timeout = 10000000LL; // 10 secs raw.sense_data = senseData; raw.sense_data_length = sizeof(kSenseSize); if (ioctl(fd, B_RAW_DEVICE_COMMAND, &raw) == 0 && raw.scsi_status == 0 && raw.cam_status == 1) { free(senseData); return B_OK; } free(senseData); return B_ERROR; }
static status_t read_table_of_contents(int deviceFD, uint32 first_session, uchar* buffer, uint16 buffer_length, bool msf) { scsi_table_of_contents_command scsi_command; raw_device_command raw_command; const uint32 sense_data_length = 1024; uchar sense_data[sense_data_length]; status_t error = buffer ? B_OK : B_BAD_VALUE; DEBUG_INIT_ETC(NULL, ("fd: %d, buffer: %p, buffer_length: %d", deviceFD, buffer, buffer_length)); if (error) return error; // Init the scsi command and copy it into the "raw scsi command" // ioctl struct memset(raw_command.command, 0, 16); scsi_command.command = 0x43; scsi_command.msf = 1; scsi_command.format = kFullTableOfContentsFormat; scsi_command.number = first_session; scsi_command.length = B_HOST_TO_BENDIAN_INT16(buffer_length); scsi_command.control = 0; scsi_command.reserved0 = scsi_command.reserved1 = scsi_command.reserved2 = scsi_command.reserved3 = scsi_command.reserved4 = scsi_command.reserved5 = scsi_command.reserved6 = 0; memcpy(raw_command.command, &scsi_command, sizeof(scsi_command)); // Init the rest of the raw command raw_command.command_length = 10; raw_command.flags = kScsiFlags; raw_command.scsi_status = 0; raw_command.cam_status = 0; raw_command.data = buffer; raw_command.data_length = buffer_length; memset(raw_command.data, 0, raw_command.data_length); raw_command.sense_data = sense_data; raw_command.sense_data_length = sense_data_length; memset(raw_command.sense_data, 0, raw_command.sense_data_length); raw_command.timeout = kScsiTimeout; if (ioctl(deviceFD, B_RAW_DEVICE_COMMAND, &raw_command) == 0) { if (raw_command.scsi_status == 0 && raw_command.cam_status == 1) { // SUCCESS!!! DBG(dump_full_table_of_contents(buffer, buffer_length)); } else { error = B_FILE_ERROR; TRACE(("%s: scsi ioctl succeeded, but scsi command failed\n", kModuleDebugName)); } } else { error = errno; TRACE(("%s: scsi command failed with error 0x%lx\n", kModuleDebugName, error)); } return error; }
static status_t get_toc(cd_driver_info *info, scsi_toc *toc) { scsi_ccb *ccb; status_t res; scsi_cmd_read_toc *cmd; size_t dataLength; scsi_toc_general *shortResponse = (scsi_toc_general *)toc->toc_data; TRACE("get_toc()\n"); ccb = info->scsi->alloc_ccb(info->scsi_device); if (ccb == NULL) return B_NO_MEMORY; // first read number of tracks only ccb->flags = SCSI_DIR_IN; cmd = (scsi_cmd_read_toc *)ccb->cdb; memset(cmd, 0, sizeof(*cmd)); cmd->opcode = SCSI_OP_READ_TOC; cmd->time = 1; cmd->format = SCSI_TOC_FORMAT_TOC; cmd->track = 1; cmd->allocation_length = B_HOST_TO_BENDIAN_INT16(sizeof(scsi_toc_general)); ccb->cdb_length = sizeof(*cmd); ccb->sort = -1; ccb->timeout = SCSI_CD_STD_TIMEOUT; ccb->data = toc->toc_data; ccb->sg_list = NULL; ccb->data_length = sizeof(toc->toc_data); res = sSCSIPeripheral->safe_exec(info->scsi_periph_device, ccb); if (res != B_OK) goto err; // then read all track infos // (little hint: number of tracks is last - first + 1; // but scsi_toc_toc has already one track, so we get // last - first extra tracks; finally, we want the lead-out as // well, so we add an extra track) dataLength = (shortResponse->last - shortResponse->first + 1) * sizeof(scsi_toc_track) + sizeof(scsi_toc_toc); dataLength = min_c(dataLength, sizeof(toc->toc_data)); TRACE(" tracks: %d - %d, data length %d\n", shortResponse->first, shortResponse->last, (int)dataLength); cmd->allocation_length = B_HOST_TO_BENDIAN_INT16(dataLength); res = sSCSIPeripheral->safe_exec(info->scsi_periph_device, ccb); err: info->scsi->free_ccb(ccb); return res; }
void MemoryView::_GetNextHexBlock(char* buffer, int32 bufferSize, const char* address) { switch(fHexMode) { case HexMode8BitInt: { snprintf(buffer, bufferSize, "%02" B_PRIx8, *((const uint8*)address)); break; } case HexMode16BitInt: { uint16 data = *((const uint16*)address); switch(fCurrentEndianMode) { case EndianModeBigEndian: { data = B_HOST_TO_BENDIAN_INT16(data); } break; case EndianModeLittleEndian: { data = B_HOST_TO_LENDIAN_INT16(data); } break; } snprintf(buffer, bufferSize, "%04" B_PRIx16, data); break; } case HexMode32BitInt: { uint32 data = *((const uint32*)address); switch(fCurrentEndianMode) { case EndianModeBigEndian: { data = B_HOST_TO_BENDIAN_INT32(data); } break; case EndianModeLittleEndian: { data = B_HOST_TO_LENDIAN_INT32(data); } break; } snprintf(buffer, bufferSize, "%08" B_PRIx32, data); break; } case HexMode64BitInt: { uint64 data = *((const uint64*)address); switch(fCurrentEndianMode) { case EndianModeBigEndian: { data = B_HOST_TO_BENDIAN_INT64(data); } break; case EndianModeLittleEndian: { data = B_HOST_TO_LENDIAN_INT64(data); } break; } snprintf(buffer, bufferSize, "%0*" B_PRIx64, 16, data); break; } } }
void PackageWriter::_WriteAttributeValue(const AttributeValue& value, uint8 encoding) { switch (value.type) { case B_HPKG_ATTRIBUTE_TYPE_INT: case B_HPKG_ATTRIBUTE_TYPE_UINT: { uint64 intValue = value.type == B_HPKG_ATTRIBUTE_TYPE_INT ? (uint64)value.signedInt : value.unsignedInt; switch (encoding) { case B_HPKG_ATTRIBUTE_ENCODING_INT_8_BIT: _Write<uint8>((uint8)intValue); break; case B_HPKG_ATTRIBUTE_ENCODING_INT_16_BIT: _Write<uint16>( B_HOST_TO_BENDIAN_INT16((uint16)intValue)); break; case B_HPKG_ATTRIBUTE_ENCODING_INT_32_BIT: _Write<uint32>( B_HOST_TO_BENDIAN_INT32((uint32)intValue)); break; case B_HPKG_ATTRIBUTE_ENCODING_INT_64_BIT: _Write<uint64>( B_HOST_TO_BENDIAN_INT64((uint64)intValue)); break; default: { fprintf(stderr, "_WriteAttributeValue(): invalid " "encoding %d for int value type %d\n", encoding, value.type); throw status_t(B_BAD_VALUE); } } break; } case B_HPKG_ATTRIBUTE_TYPE_STRING: { if (encoding == B_HPKG_ATTRIBUTE_ENCODING_STRING_TABLE) _WriteUnsignedLEB128(value.string->index); else _WriteString(value.string->string); break; } case B_HPKG_ATTRIBUTE_TYPE_RAW: { _WriteUnsignedLEB128(value.data.size); if (encoding == B_HPKG_ATTRIBUTE_ENCODING_RAW_HEAP) _WriteUnsignedLEB128(value.data.offset); else fDataWriter->WriteDataThrows(value.data.raw, value.data.size); break; } default: fprintf(stderr, "_WriteAttributeValue(): invalid value type: " "%d\n", value.type); throw status_t(B_BAD_VALUE); } }
static void ata_mode_sense_10(ide_device_info *device, ide_qrequest *qrequest) { scsi_ccb *request = qrequest->request; scsi_cmd_mode_sense_10 *cmd = (scsi_cmd_mode_sense_10 *)request->cdb; scsi_mode_param_header_10 param_header; scsi_modepage_control control; scsi_mode_param_block_desc block_desc; size_t totalLength = sizeof(scsi_mode_param_header_10) + sizeof(scsi_mode_param_block_desc) + sizeof(scsi_modepage_control); scsi_mode_param_dev_spec_da devspec = { _res0_0 : 0, dpo_fua : 0, _res0_6 : 0, write_protected : 0 }; uint32 allocationLength; SHOW_FLOW0(1, "Hi!"); allocationLength = B_BENDIAN_TO_HOST_INT16(cmd->allocation_length); // we answer control page requests and "all pages" requests // (as the latter are the same as the first) if ((cmd->page_code != SCSI_MODEPAGE_CONTROL && cmd->page_code != SCSI_MODEPAGE_ALL) || (cmd->page_control != SCSI_MODE_SENSE_PC_CURRENT && cmd->page_control != SCSI_MODE_SENSE_PC_SAVED)) { set_sense(device, SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_INV_CDB_FIELD); return; } //param_header = (scsi_mode_param_header_10 *)request->data; param_header.mode_data_length = B_HOST_TO_BENDIAN_INT16(totalLength - 1); param_header.medium_type = 0; // XXX standard is a bit vague here param_header.dev_spec_parameter = *(uint8 *)&devspec; param_header.block_desc_length = B_HOST_TO_BENDIAN_INT16(sizeof(scsi_mode_param_block_desc)); copy_sg_data(request, 0, allocationLength, ¶m_header, sizeof(param_header), false); /*block_desc = (scsi_mode_param_block_desc *)(request->data + sizeof(*param_header));*/ memset(&block_desc, 0, sizeof(block_desc)); // density is reserved (0), descriptor apply to entire medium (num_blocks=0) // remains the blocklen to be set block_desc.high_blocklen = 0; block_desc.med_blocklen = 512 >> 8; block_desc.low_blocklen = 512 & 0xff; copy_sg_data(request, sizeof(param_header), allocationLength, &block_desc, sizeof(block_desc), false); /*contr = (scsi_modepage_contr *)(request->data + sizeof(*param_header) + ((uint16)param_header->high_block_desc_len << 8) + param_header->low_block_desc_len);*/ memset(&control, 0, sizeof(control)); control.RLEC = false; control.DQue = !device->CQ_enabled; control.QErr = false; // when a command fails we requeue all // lost commands automagically control.QAM = SCSI_QAM_UNRESTRICTED; copy_sg_data(request, sizeof(param_header) + B_BENDIAN_TO_HOST_INT16(param_header.block_desc_length), allocationLength, &control, sizeof(control), false); // the number of bytes that were transferred to buffer is // restricted by allocation length and by request data buffer size totalLength = min(totalLength, allocationLength); totalLength = min(totalLength, request->data_length); request->data_resid = request->data_length - totalLength; } /*! Emulate modifying control page */ static bool ata_mode_select_control_page(ide_device_info *device, ide_qrequest *qrequest, scsi_modepage_control *page) { if (page->header.page_length != sizeof(*page) - sizeof(page->header)) { set_sense(device, SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_PARAM_LIST_LENGTH_ERR); return false; } // we only support enabling/disabling command queuing enable_CQ(device, !page->DQue); return true; } /*! Emulate MODE SELECT 10 command */ static void ata_mode_select_10(ide_device_info *device, ide_qrequest *qrequest) { scsi_ccb *request = qrequest->request; scsi_cmd_mode_select_10 *cmd = (scsi_cmd_mode_select_10 *)request->cdb; scsi_mode_param_header_10 param_header; scsi_modepage_header page_header; uint32 totalLength; uint32 modepageOffset; char modepage_buffer[64]; // !!! enlarge this to support longer mode pages if (cmd->save_pages || cmd->pf != 1) { set_sense(device, SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_INV_CDB_FIELD); return; } totalLength = min(request->data_length, B_BENDIAN_TO_HOST_INT16(cmd->param_list_length)); // first, retrieve page header to get size of different chunks //param_header = (scsi_mode_param_header_10 *)request->data; if (!copy_sg_data(request, 0, totalLength, ¶m_header, sizeof(param_header), true)) goto err; totalLength = min(totalLength, B_BENDIAN_TO_HOST_INT16(param_header.mode_data_length) + 1UL); // this is the start of the first mode page; // we ignore the block descriptor silently modepageOffset = sizeof(param_header) + B_BENDIAN_TO_HOST_INT16(param_header.block_desc_length); // go through list of pages while (modepageOffset < totalLength) { uint32 pageLength; // get header to know how long page is if (!copy_sg_data(request, modepageOffset, totalLength, &page_header, sizeof(page_header), true)) goto err; // get size of one page and copy it to buffer pageLength = page_header.page_length + sizeof(scsi_modepage_header); // the buffer has a maximum size - this is really standard compliant but // sufficient for our needs if (pageLength > sizeof(modepage_buffer)) goto err; if (!copy_sg_data(request, modepageOffset, totalLength, &modepage_buffer, min(pageLength, sizeof(modepage_buffer)), true)) goto err; // modify page; // currently, we only support the control mode page switch (page_header.page_code) { case SCSI_MODEPAGE_CONTROL: if (!ata_mode_select_control_page(device, qrequest, (scsi_modepage_control *)modepage_buffer)) return; break; default: set_sense(device, SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_INV_PARAM_LIST_FIELD); return; } modepageOffset += pageLength; } if (modepageOffset != totalLength) goto err; request->data_resid = request->data_length - totalLength; return; // if we arrive here, data length was incorrect err: set_sense(device, SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_PARAM_LIST_LENGTH_ERR); }
status_t BNetBuffer::AppendUint16(uint16 data) { uint16 be_data = B_HOST_TO_BENDIAN_INT16(data); return AppendData((const void*)&be_data, sizeof(uint16)); }
/*! Universal read/write function */ static status_t read_write(scsi_periph_device_info *device, scsi_ccb *request, io_operation *operation, uint64 offset, size_t originalNumBlocks, physical_entry* vecs, size_t vecCount, bool isWrite, size_t* _bytesTransferred) { uint32 blockSize = device->block_size; size_t numBlocks = originalNumBlocks; uint32 pos = offset; err_res res; int retries = 0; do { size_t numBytes; bool isReadWrite10 = false; request->flags = isWrite ? SCSI_DIR_OUT : SCSI_DIR_IN; // io_operations are generated by a DMAResource and thus contain DMA // safe physical vectors if (operation != NULL) request->flags |= SCSI_DMA_SAFE; // make sure we avoid 10 byte commands if they aren't supported if (!device->rw10_enabled || device->preferred_ccb_size == 6) { // restricting transfer is OK - the block manager will // take care of transferring the rest if (numBlocks > 0x100) numBlocks = 0x100; // no way to break the 21 bit address limit if (offset > 0x200000) return B_BAD_VALUE; // don't allow transfer cross the 24 bit address limit // (I'm not sure whether this is allowed, but this way we // are sure to not ask for trouble) if (offset < 0x100000) numBlocks = min_c(numBlocks, 0x100000 - pos); } numBytes = numBlocks * blockSize; if (numBlocks != originalNumBlocks) panic("I/O operation would need to be cut."); request->data = NULL; request->sg_list = vecs; request->data_length = numBytes; request->sg_count = vecCount; request->io_operation = operation; request->sort = pos; request->timeout = device->std_timeout; // see whether daemon instructed us to post an ordered command; // reset flag after read SHOW_FLOW(3, "flag=%x, next_tag=%x, ordered: %s", (int)request->flags, (int)device->next_tag_action, (request->flags & SCSI_ORDERED_QTAG) != 0 ? "yes" : "no"); // use shortest commands whenever possible if (offset + numBlocks < 0x200000LL && numBlocks <= 0x100) { scsi_cmd_rw_6 *cmd = (scsi_cmd_rw_6 *)request->cdb; isReadWrite10 = false; memset(cmd, 0, sizeof(*cmd)); cmd->opcode = isWrite ? SCSI_OP_WRITE_6 : SCSI_OP_READ_6; cmd->high_lba = (pos >> 16) & 0x1f; cmd->mid_lba = (pos >> 8) & 0xff; cmd->low_lba = pos & 0xff; cmd->length = numBlocks; request->cdb_length = sizeof(*cmd); } else if (offset + numBlocks < 0x100000000LL && numBlocks <= 0x10000) { scsi_cmd_rw_10 *cmd = (scsi_cmd_rw_10 *)request->cdb; isReadWrite10 = true; memset(cmd, 0, sizeof(*cmd)); cmd->opcode = isWrite ? SCSI_OP_WRITE_10 : SCSI_OP_READ_10; cmd->relative_address = 0; cmd->force_unit_access = 0; cmd->disable_page_out = 0; cmd->lba = B_HOST_TO_BENDIAN_INT32(pos); cmd->length = B_HOST_TO_BENDIAN_INT16(numBlocks); request->cdb_length = sizeof(*cmd); } else if (offset + numBlocks < 0x100000000LL && numBlocks <= 0x10000000) { scsi_cmd_rw_12 *cmd = (scsi_cmd_rw_12 *)request->cdb; memset(cmd, 0, sizeof(*cmd)); cmd->opcode = isWrite ? SCSI_OP_WRITE_12 : SCSI_OP_READ_12; cmd->relative_address = 0; cmd->force_unit_access = 0; cmd->disable_page_out = 0; cmd->lba = B_HOST_TO_BENDIAN_INT32(pos); cmd->length = B_HOST_TO_BENDIAN_INT32(numBlocks); request->cdb_length = sizeof(*cmd); } else { scsi_cmd_rw_16 *cmd = (scsi_cmd_rw_16 *)request->cdb; memset(cmd, 0, sizeof(*cmd)); cmd->opcode = isWrite ? SCSI_OP_WRITE_16 : SCSI_OP_READ_16; cmd->force_unit_access_non_volatile = 0; cmd->force_unit_access = 0; cmd->disable_page_out = 0; cmd->lba = B_HOST_TO_BENDIAN_INT64(offset); cmd->length = B_HOST_TO_BENDIAN_INT32(numBlocks); request->cdb_length = sizeof(*cmd); } // TODO: last chance to detect errors that occured during concurrent accesses //status_t status = handle->pending_error; //if (status != B_OK) // return status; device->scsi->async_io(request); acquire_sem(request->completion_sem); // ask generic peripheral layer what to do now res = periph_check_error(device, request); // TODO: bytes might have been transferred even in the error case! switch (res.action) { case err_act_ok: *_bytesTransferred = numBytes - request->data_resid; break; case err_act_start: res = periph_send_start_stop(device, request, 1, device->removable); if (res.action == err_act_ok) res.action = err_act_retry; break; case err_act_invalid_req: // if this was a 10 byte command, the device probably doesn't // support them, so disable them and retry if (isReadWrite10) { atomic_and(&device->rw10_enabled, 0); res.action = err_act_retry; } else res.action = err_act_fail; break; } } while ((res.action == err_act_retry && retries++ < 3)
status_t Flap::AddInt16(int16 value) { int16 v = B_HOST_TO_BENDIAN_INT16(value); return AddRawData((uchar *)&v, sizeof(value)); };