Пример #1
0
int scsi_write(int block_start, int block_count, char *data) {
    int rc;

    if (scsi == NULL)
        return -1;

    rc = scsi_read_write(SCSI_WRITE, block_start, block_count, data);

    return rc;
}
Пример #2
0
static void
rtems_bsd_csio_callback(struct cam_periph *periph, union ccb *ccb)
{
	rtems_status_code sc = RTEMS_SUCCESSFUL;
	bool done = false;
	struct cam_sim *sim = ccb->ccb_h.sim;

	BSD_ASSERT(periph == NULL && sim->state == BSD_SIM_BUSY);

	if (ccb->ccb_h.status == CAM_REQ_CMP) {
		rtems_blkdev_sg_buffer *sg = ccb->csio.sg_current;

		if (sg != ccb->csio.sg_end) {
			scsi_read_write(
				&ccb->csio,
				BSD_SCSI_RETRIES,
				rtems_bsd_csio_callback,
				BSD_SCSI_TAG,
				ccb->csio.readop,
				0,
				BSD_SCSI_MIN_COMMAND_SIZE,
				sg->block,
				sg->length / 512, /* FIXME */
				sg->buffer,
				sg->length,
				SSD_FULL_SIZE,
				BSD_SCSI_TIMEOUT
			);
			ccb->csio.sg_current = sg + 1;
			(*sim->sim_action)(sim, ccb);
		} else {
			done = true;
		}
	} else if (ccb->ccb_h.status == CAM_SEL_TIMEOUT) {
		sc = RTEMS_UNSATISFIED;
		done = true;
	} else {
		sc = RTEMS_IO_ERROR;
		done = true;
	}

	if (done) {
		ccb->csio.req->req_done(ccb->csio.req->done_arg, sc);
		rtems_bsd_sim_set_state_and_notify(sim, BSD_SIM_IDLE);
	}
}
Пример #3
0
/*
 * Read a number of blocks from the drive
 */
static int scsi_read_write(int dir, int block_start,
                           int block_count, char *data) {
    int transfer_len;
    int rc;

    /* Command to SCSI server on the USB mass storage device */
    struct command_descriptor_block6 cdb6 = {
        .op_code = (dir == SCSI_READ) ? CDB_READ6: CDB_WRITE6,
        .length = block_count,  /* Unit of sectors */
        .control = 0
    };
    /*
     * Copy address omitting the first byte
     * (SCSI addresses are 19bits long)
     */
    cdb6.block_address[0] = (block_start >> 16) & 0x1f;
    cdb6.block_address[1] = (block_start >> 8) & 0xff;
    cdb6.block_address[2] = block_start & 0xff;

    transfer_len = block_count * scsi->block_size;

    spinlock_acquire(&scsi->lock);
    if (dir == SCSI_READ)
        rc = scsi->read(scsi->driver, 6, (char *)&cdb6,
                        transfer_len, data);
    else
        rc = scsi->write(scsi->driver, 6, (char *)&cdb6,
                         transfer_len, data);
    spinlock_release(&scsi->lock);

    return rc;
}

/*
 * SCSI interface functions
 */
int scsi_read(int block_start, int block_count, char *data) {
    int rc;

    if (scsi == NULL)
        return -1;

    rc = scsi_read_write(SCSI_READ, block_start, block_count, data);

    return rc;
}