/* * A workaround for flash memory I/O errors when the internal hard disk * has not been formatted for OtherOS use. Delay disk close until flash * memory is closed.
*/
staticstruct ps3_flash_workaround { int flash_open; int disk_open; struct ps3_system_bus_device *disk_sbd;
} ps3_flash_workaround;
staticint ps3stor_open_hv_device(struct ps3_system_bus_device *sbd)
{ int error = ps3_open_hv_device(sbd);
if (error) return error;
if (sbd->match_id == PS3_MATCH_ID_STOR_FLASH)
ps3_flash_workaround.flash_open = 1;
if (sbd->match_id == PS3_MATCH_ID_STOR_DISK)
ps3_flash_workaround.disk_open = 1;
return 0;
}
staticint ps3stor_close_hv_device(struct ps3_system_bus_device *sbd)
{ int error;
if (dev->sbd.match_id == PS3_MATCH_ID_STOR_ROM) { /* special case: CD-ROM is assumed always accessible */
dev->accessible_regions = 1; return 0;
}
error = -EPERM; for (i = 0; i < dev->num_regions; i++) {
dev_dbg(&dev->sbd.core, "%s:%u: checking accessibility of region %u\n",
__func__, __LINE__, i);
dev->region_idx = i;
res = ps3stor_read_write_sectors(dev, dev->bounce_lpar, 0, 1,
0); if (res) {
dev_dbg(&dev->sbd.core, "%s:%u: read failed, " "region %u is not accessible\n", __func__,
__LINE__, i); continue;
}
dev_dbg(&dev->sbd.core, "%s:%u: region %u is accessible\n",
__func__, __LINE__, i);
set_bit(i, &dev->accessible_regions);
/* We can access at least one region */
error = 0;
} if (error) return error;
n = hweight_long(dev->accessible_regions); if (n > 1)
dev_info(&dev->sbd.core, "%s:%u: %lu accessible regions found. Only the first " "one will be used\n",
__func__, __LINE__, n);
dev->region_idx = __ffs(dev->accessible_regions);
dev_info(&dev->sbd.core, "First accessible region has index %u start %llu size %llu\n",
dev->region_idx, dev->regions[dev->region_idx].start,
dev->regions[dev->region_idx].size);
return 0;
}
/** * ps3stor_setup - Setup a storage device before use * @dev: Pointer to a struct ps3_storage_device * @handler: Pointer to an interrupt handler * * Returns 0 for success, or an error code
*/ int ps3stor_setup(struct ps3_storage_device *dev, irq_handler_t handler)
{ int error, res, alignment; enum ps3_dma_page_size page_size;
/** * ps3stor_teardown - Tear down a storage device after use * @dev: Pointer to a struct ps3_storage_device
*/ void ps3stor_teardown(struct ps3_storage_device *dev)
{ int error;
/** * ps3stor_read_write_sectors - read/write from/to a storage device * @dev: Pointer to a struct ps3_storage_device * @lpar: HV logical partition address * @start_sector: First sector to read/write * @sectors: Number of sectors to read/write * @write: Flag indicating write (non-zero) or read (zero) * * Returns 0 for success, -1 in case of failure to submit the command, or * an LV1 status value in case of other errors
*/
u64 ps3stor_read_write_sectors(struct ps3_storage_device *dev, u64 lpar,
u64 start_sector, u64 sectors, int write)
{ unsignedint region_id = dev->regions[dev->region_idx].id; constchar *op = write ? "write" : "read"; int res;
/** * ps3stor_send_command - send a device command to a storage device * @dev: Pointer to a struct ps3_storage_device * @cmd: Command number * @arg1: First command argument * @arg2: Second command argument * @arg3: Third command argument * @arg4: Fourth command argument * * Returns 0 for success, -1 in case of failure to submit the command, or * an LV1 status value in case of other errors
*/
u64 ps3stor_send_command(struct ps3_storage_device *dev, u64 cmd, u64 arg1,
u64 arg2, u64 arg3, u64 arg4)
{ int res;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.