int encdec_send_device_command(u64 cmd, u8 *send_data, u64 send_data_size, u8 *recv_data, u64 recv_data_size) { u64 tag, status, ticks; int result; memset(encdec_buf, 0, ENCDEC_DMA_SIZE); memcpy(encdec_buf, send_data, send_data_size); result = lv1_storage_send_device_command(ENCDEC_DEV_ID, cmd, encdec_buf_lpar_addr, send_data_size, encdec_buf_lpar_addr + send_data_size, recv_data_size, &tag); if (result != 0) return result; for (;;) { result = lv1_storage_check_async_status(ENCDEC_DEV_ID, tag, &status); if (result != 0) continue; if (status == 0) break; ticks = TB_TICKS_PER_SEC / 10; sleep(ticks); } memcpy(recv_data, encdec_buf + send_data_size, recv_data_size); return 0; }
int ps3stor_read_sectors(struct ps3_stordev *sd, int regidx, uint64_t start_sector, uint64_t sector_count, uint64_t flags, char *buf) { #define MIN(a, b) ((a) <= (b) ? (a) : (b)) #define BOUNCE_SECTORS (sizeof(dma_buf) / sd->sd_blksize) #define ASYNC_STATUS_POLL_PERIOD 100 /* microseconds */ struct ps3_storreg *reg = &sd->sd_regs[regidx]; uint64_t nleft, nread, nsectors; uint64_t tag, status; unsigned int timeout; int err = 0; nleft = sector_count; nread = 0; while (nleft) { nsectors = MIN(nleft, BOUNCE_SECTORS); err = lv1_storage_read(sd->sd_devid, reg->sr_id, start_sector + nread, nsectors, flags, (uint32_t)dma_buf, &tag); if (err) return err; timeout = 5000000; /* microseconds */ while (1) { if (timeout < ASYNC_STATUS_POLL_PERIOD) return ETIMEDOUT; err = lv1_storage_check_async_status(sd->sd_devid, tag, &status); if (!err && !status) break; delay(ASYNC_STATUS_POLL_PERIOD); timeout -= ASYNC_STATUS_POLL_PERIOD; } if (status != 0) return EIO; memcpy(buf + nread * sd->sd_blksize, (u_char *)dma_buf, nsectors * sd->sd_blksize); nread += nsectors; nleft -= nsectors; } return err; #undef MIN #undef BOUNCE_SECTORS #undef ASYNC_STATUS_POLL_PERIOD }
static int ps3stor_wait_for_completion(u64 dev_id, u64 tag, unsigned int timeout) { int result = -1; unsigned int retries = 0; u64 status; for (retries = 0; retries < timeout; retries++) { result = lv1_storage_check_async_status(dev_id, tag, &status); if (!result) break; msleep(1); } if (result) pr_debug("%s:%u: check_async_status: %s, status %lx\n", __func__, __LINE__, ps3_result(result), status); return result; }
int lv1_stor_wrapper_read(lv1_stor_wrapper_var *stor_var, u64 region_id, u64 start_sector, u64 num_sectors, u64 flags, void *data) { u64 tag, status; int result; result = lv1_storage_read(stor_var->dev_id, region_id, start_sector, num_sectors, flags, stor_var->dma_lpar_addr, &tag); if (result != 0) return result; for (;;) { result = lv1_storage_check_async_status(stor_var->dev_id, tag, &status); if (result != 0) continue; if (status == 0) break; } memcpy(data, stor_var->dma, stor_var->block_size * num_sectors); return 0; }