/* * Don't return -ERESTARTSYS if we can't get a token, the MTD core * might have split up the call from userspace and called into the * driver more than once, we'll already have done some amount of work.
*/ staticint powernv_flash_async_op(struct mtd_info *mtd, enum flash_op op,
loff_t offset, size_t len, size_t *retlen, u_char *buf)
{ struct powernv_flash *info = (struct powernv_flash *)mtd->priv; struct device *dev = &mtd->dev; int token; struct opal_msg msg; int rc;
if (rc == OPAL_ASYNC_COMPLETION) {
rc = opal_async_wait_response_interruptible(token, &msg); if (rc) { /* * If we return the mtd core will free the * buffer we've just passed to OPAL but OPAL * will continue to read or write from that * memory. * It may be tempting to ultimately return 0 * if we're doing a read or a write since we * are going to end up waiting until OPAL is * done. However, because the MTD core sends * us the userspace request in chunks, we need * it to know we've been interrupted.
*/
rc = -EINTR; if (opal_async_wait_response(token, &msg))
dev_err(dev, "opal_async_wait_response() failed\n"); goto out;
}
rc = opal_get_async_rc(msg);
}
/* * OPAL does mutual exclusion on the flash, it will return * OPAL_BUSY. * During firmware updates by the service processor OPAL may * be (temporarily) prevented from accessing the flash, in * this case OPAL will also return OPAL_BUSY. * Both cases aren't errors exactly but the flash could have * changed, userspace should be informed.
*/ if (rc != OPAL_SUCCESS && rc != OPAL_BUSY)
dev_err(dev, "opal_flash_async_op(op=%d) failed (rc %d)\n",
op, rc);
/** * powernv_flash_read * @mtd: the device * @from: the offset to read from * @len: the number of bytes to read * @retlen: the number of bytes actually read * @buf: the filled in buffer * * Returns 0 if read successful, or -ERRNO if an error occurred
*/ staticint powernv_flash_read(struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, u_char *buf)
{ return powernv_flash_async_op(mtd, FLASH_OP_READ, from,
len, retlen, buf);
}
/** * powernv_flash_write * @mtd: the device * @to: the offset to write to * @len: the number of bytes to write * @retlen: the number of bytes actually written * @buf: the buffer to get bytes from * * Returns 0 if write successful, -ERRNO if error occurred
*/ staticint powernv_flash_write(struct mtd_info *mtd, loff_t to, size_t len,
size_t *retlen, const u_char *buf)
{ return powernv_flash_async_op(mtd, FLASH_OP_WRITE, to,
len, retlen, (u_char *)buf);
}
/** * powernv_flash_erase * @mtd: the device * @erase: the erase info * Returns 0 if erase successful or -ERRNO if an error occurred
*/ staticint powernv_flash_erase(struct mtd_info *mtd, struct erase_info *erase)
{ int rc;
/** * powernv_flash_set_driver_info - Fill the mtd_info structure and docg3 * @dev: The device structure * @mtd: The structure to fill
*/ staticint powernv_flash_set_driver_info(struct device *dev, struct mtd_info *mtd)
{
u64 size;
u32 erase_size; int rc;
rc = of_property_read_u32(dev->of_node, "ibm,flash-block-size",
&erase_size); if (rc) {
dev_err(dev, "couldn't get resource block size information\n"); return rc;
}
rc = of_property_read_u64(dev->of_node, "reg", &size); if (rc) {
dev_err(dev, "couldn't get resource size information\n"); return rc;
}
/* * Going to have to check what details I need to set and how to * get them
*/
mtd->name = devm_kasprintf(dev, GFP_KERNEL, "%pOFP", dev->of_node); if (!mtd->name) return -ENOMEM;
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); if (!data) return -ENOMEM;
data->mtd.priv = data;
ret = of_property_read_u32(dev->of_node, "ibm,opal-id", &(data->id)); if (ret) {
dev_err(dev, "no device property 'ibm,opal-id'\n"); return ret;
}
ret = powernv_flash_set_driver_info(dev, &data->mtd); if (ret) return ret;
dev_set_drvdata(dev, data);
/* * The current flash that skiboot exposes is one contiguous flash chip * with an ffs partition at the start, it should prove easier for users * to deal with partitions or not as they see fit
*/ return mtd_device_register(&data->mtd, NULL, 0);
}
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.