int rpcbuf::overflow(int c) { if (!_opened || allocate() == EOF) { return EOF; } if (c == EOF) { finish_request(); } if (rptr() == pbase() && pptr() >= epptr() && !expand_p()) { error("rpcbuf::overflow: out of memory"); return EOF; } int nwrite = (rptr() >= pbase()) ? rptr() - pbase() : out_waiting(); int count = 0; while (count < nwrite) { int nsent = write(_fd, pbase() + count, nwrite - count); if (nsent < 0) { sys_error("rpcbuf::overflow: write"); return EOF; } count += nsent; } if (rptr() > pbase()) { Memory::copy(rptr(), pbase(), pptr() - rptr()); rbump(-nwrite); } pbump(-nwrite); if (c != EOF) { sputc(c); } return zapeof(c); }
static void process_response(void *callback_data) { struct transfer_request *request = (struct transfer_request *)callback_data; finish_request(request); }
/** * Process the next record of the given request context. * When done, submit the reply and free the resources of * the rc. * * @param rc context to process */ static void submit_request (struct ReplyContext *rc) { struct GNUNET_DNSPARSER_Record *ra; unsigned int ra_len; unsigned int i; while (1) { switch (rc->group) { case ANSWERS: ra = rc->dns->answers; ra_len = rc->dns->num_answers; break; case AUTHORITY_RECORDS: ra = rc->dns->authority_records; ra_len = rc->dns->num_authority_records; break; case ADDITIONAL_RECORDS: ra = rc->dns->additional_records; ra_len = rc->dns->num_additional_records; break; case END: finish_request (rc); return; default: GNUNET_assert (0); } for (i=rc->offset;i<ra_len;i++) { switch (ra[i].type) { case GNUNET_DNSPARSER_TYPE_A: if (ipv4_pt) { rc->offset = i + 1; modify_address (rc, &ra[i]); return; } break; case GNUNET_DNSPARSER_TYPE_AAAA: if (ipv6_pt) { rc->offset = i + 1; modify_address (rc, &ra[i]); return; } break; } } rc->group++; } }
int rpcbuf::start_request() { if (!_mystream || !_opened || allocate() == EOF) { return EOF; } finish_request(); setr(pptr()); const int length = 0; mystream().width(FIELDWIDTH); mystream() << length; _actualWidth = pptr() - rptr(); return 0; }
/*! Execute SCSI command */ void ata_exec_io(ide_device_info *device, ide_qrequest *qrequest) { scsi_ccb *request = qrequest->request; SHOW_FLOW(3, "command=%x", request->cdb[0]); // ATA devices have one LUN only if (request->target_lun != 0) { request->subsys_status = SCSI_SEL_TIMEOUT; finish_request(qrequest, false); return; } // starting a request means deleting sense, so don't do it if // the command wants to read it if (request->cdb[0] != SCSI_OP_REQUEST_SENSE) start_request(device, qrequest); switch (request->cdb[0]) { case SCSI_OP_TEST_UNIT_READY: ata_test_unit_ready(device, qrequest); break; case SCSI_OP_REQUEST_SENSE: ide_request_sense(device, qrequest); return; case SCSI_OP_FORMAT: /* FORMAT UNIT */ // we could forward request to disk, but modern disks cannot // be formatted anyway, so we just refuse request // (exceptions are removable media devices, but to my knowledge // they don't have to be formatted as well) set_sense(device, SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_INV_OPCODE); break; case SCSI_OP_INQUIRY: ata_inquiry(device, qrequest); break; case SCSI_OP_MODE_SELECT_10: ata_mode_select_10(device, qrequest); break; case SCSI_OP_MODE_SENSE_10: ata_mode_sense_10(device, qrequest); break; case SCSI_OP_MODE_SELECT_6: case SCSI_OP_MODE_SENSE_6: // we've told SCSI bus manager to emulates these commands set_sense(device, SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_INV_OPCODE); break; case SCSI_OP_RESERVE: case SCSI_OP_RELEASE: // though mandatory, this doesn't make much sense in a // single initiator environment; so what set_sense(device, SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_INV_OPCODE); break; case SCSI_OP_START_STOP: { scsi_cmd_ssu *cmd = (scsi_cmd_ssu *)request->cdb; // with no LoEj bit set, we should only allow/deny further access // we ignore that (unsupported for ATA) // with LoEj bit set, we should additionally either load or eject the medium // (start = 0 - eject; start = 1 - load) if (!cmd->start) // we must always flush cache if start = 0 ata_flush_cache(device, qrequest); if (cmd->load_eject) ata_load_eject(device, qrequest, cmd->start); break; } case SCSI_OP_PREVENT_ALLOW: { scsi_cmd_prevent_allow *cmd = (scsi_cmd_prevent_allow *)request->cdb; ata_prevent_allow(device, cmd->prevent); break; } case SCSI_OP_READ_CAPACITY: read_capacity(device, qrequest); break; case SCSI_OP_VERIFY: // does anyone uses this function? // effectly, it does a read-and-compare, which IDE doesn't support set_sense(device, SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_INV_OPCODE); break; case SCSI_OP_SYNCHRONIZE_CACHE: // we ignore range and immediate bit, we always immediately flush everything ata_flush_cache(device, qrequest); break; // sadly, there are two possible read/write operation codes; // at least, the third one, read/write(12), is not valid for DAS case SCSI_OP_READ_6: case SCSI_OP_WRITE_6: { scsi_cmd_rw_6 *cmd = (scsi_cmd_rw_6 *)request->cdb; uint32 pos; size_t length; pos = ((uint32)cmd->high_lba << 16) | ((uint32)cmd->mid_lba << 8) | (uint32)cmd->low_lba; length = cmd->length != 0 ? cmd->length : 256; SHOW_FLOW(3, "READ6/WRITE6 pos=%lx, length=%lx", pos, length); ata_send_rw(device, qrequest, pos, length, cmd->opcode == SCSI_OP_WRITE_6); return; } case SCSI_OP_READ_10: case SCSI_OP_WRITE_10: { scsi_cmd_rw_10 *cmd = (scsi_cmd_rw_10 *)request->cdb; uint32 pos; size_t length; pos = B_BENDIAN_TO_HOST_INT32(cmd->lba); length = B_BENDIAN_TO_HOST_INT16(cmd->length); if (length != 0) { ata_send_rw(device, qrequest, pos, length, cmd->opcode == SCSI_OP_WRITE_10); } else { // we cannot transfer zero blocks (apart from LBA48) finish_request(qrequest, false); } return; } default: set_sense(device, SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_INV_OPCODE); } finish_checksense(qrequest); }
void finish_retry( ide_qrequest *qrequest ) { qrequest->request->cam_ch.cam_status = CAM_RESUBMIT; qrequest->device->combined_sense = 0; finish_request( qrequest ); }