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; }
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); } }
/* * 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; }