diff --git a/arch/arm/boot/dts/npcm750.dts b/arch/arm/boot/dts/npcm750.dts index 1e6bd0260958a1..10a7555e2d28ad 100755 --- a/arch/arm/boot/dts/npcm750.dts +++ b/arch/arm/boot/dts/npcm750.dts @@ -234,6 +234,20 @@ status = "okay"; }; + /* lm75 on SVB */ + i2c0: i2c-bus@f0080000 { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + lm75@48 { + compatible = "lm75"; + reg = <0x48>; + status = "okay"; + }; + }; + + /* lm75 on EB */ i2c1: i2c-bus@f0081000 { #address-cells = <1>; #size-cells = <0>; @@ -246,6 +260,7 @@ }; }; + /* tmp100 on EB */ i2c2: i2c-bus@f0082000 { #address-cells = <1>; #size-cells = <0>; @@ -257,6 +272,19 @@ status = "okay"; }; }; + + /* tmp100 on SVB */ + i2c6: i2c-bus@f0086000 { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + tmp100@48 { + compatible = "tmp100"; + reg = <0x48>; + status = "okay"; + }; + }; }; diff --git a/arch/arm/mach-npcmX50/include/mach/chip_npcm750.h b/arch/arm/mach-npcmX50/include/mach/chip_npcm750.h index 6bd161972107e9..b1f5a893b2f870 100755 --- a/arch/arm/mach-npcmX50/include/mach/chip_npcm750.h +++ b/arch/arm/mach-npcmX50/include/mach/chip_npcm750.h @@ -326,6 +326,8 @@ #define NPCMX50_SMB_INTERRUPT(module) (NPCMX50_SMB_INTERRUPT_0 + module) +#define SMB_NUM_OF_MODULES 16 + /*---------------------------------------------------------------------------------------------------------*/ /* KCS Module */ diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c deleted file mode 100755 index d275a722fa4f44..00000000000000 --- a/drivers/mmc/card/block.c +++ /dev/null @@ -1,2610 +0,0 @@ -/* - * Block driver for media (i.e., flash cards) - * - * Copyright 2002 Hewlett-Packard Company - * Copyright 2005-2008 Pierre Ossman - * - * Use consistent with the GNU GPL is permitted, - * provided that this copyright notice is - * preserved in its entirety in all copies and derived works. - * - * HEWLETT-PACKARD COMPANY MAKES NO WARRANTIES, EXPRESSED OR IMPLIED, - * AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS - * FITNESS FOR ANY PARTICULAR PURPOSE. - * - * Many thanks to Alessandro Rubini and Jonathan Corbet! - * - * Author: Andrew Christian - * 28 May 2002 - */ -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -#include "queue.h" - -MODULE_ALIAS("mmc:block"); -#ifdef MODULE_PARAM_PREFIX -#undef MODULE_PARAM_PREFIX -#endif -#define MODULE_PARAM_PREFIX "mmcblk." - -#define INAND_CMD38_ARG_EXT_CSD 113 -#define INAND_CMD38_ARG_ERASE 0x00 -#define INAND_CMD38_ARG_TRIM 0x01 -#define INAND_CMD38_ARG_SECERASE 0x80 -#define INAND_CMD38_ARG_SECTRIM1 0x81 -#define INAND_CMD38_ARG_SECTRIM2 0x88 -#define MMC_BLK_TIMEOUT_MS (10 * 60 * 1000) /* 10 minute timeout */ -#define MMC_SANITIZE_REQ_TIMEOUT 240000 -#define MMC_EXTRACT_INDEX_FROM_ARG(x) ((x & 0x00FF0000) >> 16) - -#define mmc_req_rel_wr(req) (((req->cmd_flags & REQ_FUA) || \ - (req->cmd_flags & REQ_META)) && \ - (rq_data_dir(req) == WRITE)) -#define PACKED_CMD_VER 0x01 -#define PACKED_CMD_WR 0x02 - -static DEFINE_MUTEX(block_mutex); - -/* - * The defaults come from config options but can be overriden by module - * or bootarg options. - */ -static int perdev_minors = CONFIG_MMC_BLOCK_MINORS; - -/* - * We've only got one major, so number of mmcblk devices is - * limited to (1 << 20) / number of minors per device. It is also - * currently limited by the size of the static bitmaps below. - */ -static int max_devices; - -#define MAX_DEVICES 256 - -/* TODO: Replace these with struct ida */ -static DECLARE_BITMAP(dev_use, MAX_DEVICES); -static DECLARE_BITMAP(name_use, MAX_DEVICES); - -/* - * There is one mmc_blk_data per slot. - */ -struct mmc_blk_data { - spinlock_t lock; - struct gendisk *disk; - struct mmc_queue queue; - struct list_head part; - - unsigned int flags; -#define MMC_BLK_CMD23 (1 << 0) /* Can do SET_BLOCK_COUNT for multiblock */ -#define MMC_BLK_REL_WR (1 << 1) /* MMC Reliable write support */ -#define MMC_BLK_PACKED_CMD (1 << 2) /* MMC packed command support */ - - unsigned int usage; - unsigned int read_only; - unsigned int part_type; - unsigned int name_idx; - unsigned int reset_done; -#define MMC_BLK_READ BIT(0) -#define MMC_BLK_WRITE BIT(1) -#define MMC_BLK_DISCARD BIT(2) -#define MMC_BLK_SECDISCARD BIT(3) - - /* - * Only set in main mmc_blk_data associated - * with mmc_card with dev_set_drvdata, and keeps - * track of the current selected device partition. - */ - unsigned int part_curr; - struct device_attribute force_ro; - struct device_attribute power_ro_lock; - int area_type; -}; - -static DEFINE_MUTEX(open_lock); - -enum { - MMC_PACKED_NR_IDX = -1, - MMC_PACKED_NR_ZERO, - MMC_PACKED_NR_SINGLE, -}; - -module_param(perdev_minors, int, 0444); -MODULE_PARM_DESC(perdev_minors, "Minors numbers to allocate per device"); - -static inline int mmc_blk_part_switch(struct mmc_card *card, - struct mmc_blk_data *md); -static int get_card_status(struct mmc_card *card, u32 *status, int retries); - -static inline void mmc_blk_clear_packed(struct mmc_queue_req *mqrq) -{ - struct mmc_packed *packed = mqrq->packed; - - BUG_ON(!packed); - - mqrq->cmd_type = MMC_PACKED_NONE; - packed->nr_entries = MMC_PACKED_NR_ZERO; - packed->idx_failure = MMC_PACKED_NR_IDX; - packed->retries = 0; - packed->blocks = 0; -} - -static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk) -{ - struct mmc_blk_data *md; - - mutex_lock(&open_lock); - md = disk->private_data; - if (md && md->usage == 0) - md = NULL; - if (md) - md->usage++; - mutex_unlock(&open_lock); - - return md; -} - -static inline int mmc_get_devidx(struct gendisk *disk) -{ - int devmaj = MAJOR(disk_devt(disk)); - int devidx = MINOR(disk_devt(disk)) / perdev_minors; - - if (!devmaj) - devidx = disk->first_minor / perdev_minors; - return devidx; -} - -static void mmc_blk_put(struct mmc_blk_data *md) -{ - mutex_lock(&open_lock); - md->usage--; - if (md->usage == 0) { - int devidx = mmc_get_devidx(md->disk); - blk_cleanup_queue(md->queue.queue); - - __clear_bit(devidx, dev_use); - - put_disk(md->disk); - kfree(md); - } - mutex_unlock(&open_lock); -} - -static ssize_t power_ro_lock_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - int ret; - struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev)); - struct mmc_card *card = md->queue.card; - int locked = 0; - - if (card->ext_csd.boot_ro_lock & EXT_CSD_BOOT_WP_B_PERM_WP_EN) - locked = 2; - else if (card->ext_csd.boot_ro_lock & EXT_CSD_BOOT_WP_B_PWR_WP_EN) - locked = 1; - - ret = snprintf(buf, PAGE_SIZE, "%d\n", locked); - - mmc_blk_put(md); - - return ret; -} - -static ssize_t power_ro_lock_store(struct device *dev, - struct device_attribute *attr, const char *buf, size_t count) -{ - int ret; - struct mmc_blk_data *md, *part_md; - struct mmc_card *card; - unsigned long set; - - if (kstrtoul(buf, 0, &set)) - return -EINVAL; - - if (set != 1) - return count; - - md = mmc_blk_get(dev_to_disk(dev)); - card = md->queue.card; - - mmc_get_card(card); - - ret = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_WP, - card->ext_csd.boot_ro_lock | - EXT_CSD_BOOT_WP_B_PWR_WP_EN, - card->ext_csd.part_time); - if (ret) - pr_err("%s: Locking boot partition ro until next power on failed: %d\n", md->disk->disk_name, ret); - else - card->ext_csd.boot_ro_lock |= EXT_CSD_BOOT_WP_B_PWR_WP_EN; - - mmc_put_card(card); - - if (!ret) { - pr_info("%s: Locking boot partition ro until next power on\n", - md->disk->disk_name); - set_disk_ro(md->disk, 1); - - list_for_each_entry(part_md, &md->part, part) - if (part_md->area_type == MMC_BLK_DATA_AREA_BOOT) { - pr_info("%s: Locking boot partition ro until next power on\n", part_md->disk->disk_name); - set_disk_ro(part_md->disk, 1); - } - } - - mmc_blk_put(md); - return count; -} - -static ssize_t force_ro_show(struct device *dev, struct device_attribute *attr, - char *buf) -{ - int ret; - struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev)); - - ret = snprintf(buf, PAGE_SIZE, "%d\n", - get_disk_ro(dev_to_disk(dev)) ^ - md->read_only); - mmc_blk_put(md); - return ret; -} - -static ssize_t force_ro_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - int ret; - char *end; - struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev)); - unsigned long set = simple_strtoul(buf, &end, 0); - if (end == buf) { - ret = -EINVAL; - goto out; - } - - set_disk_ro(dev_to_disk(dev), set || md->read_only); - ret = count; -out: - mmc_blk_put(md); - return ret; -} - -static int mmc_blk_open(struct block_device *bdev, fmode_t mode) -{ - struct mmc_blk_data *md = mmc_blk_get(bdev->bd_disk); - int ret = -ENXIO; - - mutex_lock(&block_mutex); - if (md) { - if (md->usage == 2) - check_disk_change(bdev); - ret = 0; - - if ((mode & FMODE_WRITE) && md->read_only) { - mmc_blk_put(md); - ret = -EROFS; - } - } - mutex_unlock(&block_mutex); - - return ret; -} - -static void mmc_blk_release(struct gendisk *disk, fmode_t mode) -{ - struct mmc_blk_data *md = disk->private_data; - - mutex_lock(&block_mutex); - mmc_blk_put(md); - mutex_unlock(&block_mutex); -} - -static int -mmc_blk_getgeo(struct block_device *bdev, struct hd_geometry *geo) -{ - geo->cylinders = get_capacity(bdev->bd_disk) / (4 * 16); - geo->heads = 4; - geo->sectors = 16; - return 0; -} - -struct mmc_blk_ioc_data { - struct mmc_ioc_cmd ic; - unsigned char *buf; - u64 buf_bytes; -}; - -static struct mmc_blk_ioc_data *mmc_blk_ioctl_copy_from_user( - struct mmc_ioc_cmd __user *user) -{ - struct mmc_blk_ioc_data *idata; - int err; - - idata = kzalloc(sizeof(*idata), GFP_KERNEL); - if (!idata) { - err = -ENOMEM; - goto out; - } - - if (copy_from_user(&idata->ic, user, sizeof(idata->ic))) { - err = -EFAULT; - goto idata_err; - } - - idata->buf_bytes = (u64) idata->ic.blksz * idata->ic.blocks; - if (idata->buf_bytes > MMC_IOC_MAX_BYTES) { - err = -EOVERFLOW; - goto idata_err; - } - - if (!idata->buf_bytes) - return idata; - - idata->buf = kzalloc(idata->buf_bytes, GFP_KERNEL); - if (!idata->buf) { - err = -ENOMEM; - goto idata_err; - } - - if (copy_from_user(idata->buf, (void __user *)(unsigned long) - idata->ic.data_ptr, idata->buf_bytes)) { - err = -EFAULT; - goto copy_err; - } - - return idata; - -copy_err: - kfree(idata->buf); -idata_err: - kfree(idata); -out: - return ERR_PTR(err); -} - -static int ioctl_rpmb_card_status_poll(struct mmc_card *card, u32 *status, - u32 retries_max) -{ - int err; - u32 retry_count = 0; - - if (!status || !retries_max) - return -EINVAL; - - do { - err = get_card_status(card, status, 5); - if (err) - break; - - if (!R1_STATUS(*status) && - (R1_CURRENT_STATE(*status) != R1_STATE_PRG)) - break; /* RPMB programming operation complete */ - - /* - * Rechedule to give the MMC device a chance to continue - * processing the previous command without being polled too - * frequently. - */ - usleep_range(1000, 5000); - } while (++retry_count < retries_max); - - if (retry_count == retries_max) - err = -EPERM; - - return err; -} - -static int ioctl_do_sanitize(struct mmc_card *card) -{ - int err; - - if (!mmc_can_sanitize(card)) { - pr_warn("%s: %s - SANITIZE is not supported\n", - mmc_hostname(card->host), __func__); - err = -EOPNOTSUPP; - goto out; - } - - pr_debug("%s: %s - SANITIZE IN PROGRESS...\n", - mmc_hostname(card->host), __func__); - - err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, - EXT_CSD_SANITIZE_START, 1, - MMC_SANITIZE_REQ_TIMEOUT); - - if (err) - pr_err("%s: %s - EXT_CSD_SANITIZE_START failed. err=%d\n", - mmc_hostname(card->host), __func__, err); - - pr_debug("%s: %s - SANITIZE COMPLETED\n", mmc_hostname(card->host), - __func__); -out: - return err; -} - -static int mmc_blk_ioctl_cmd(struct block_device *bdev, - struct mmc_ioc_cmd __user *ic_ptr) -{ - struct mmc_blk_ioc_data *idata; - struct mmc_blk_data *md; - struct mmc_card *card; - struct mmc_command cmd = {0}; - struct mmc_data data = {0}; - struct mmc_request mrq = {NULL}; - struct scatterlist sg; - int err; - int is_rpmb = false; - u32 status = 0; - - /* - * The caller must have CAP_SYS_RAWIO, and must be calling this on the - * whole block device, not on a partition. This prevents overspray - * between sibling partitions. - */ - if ((!capable(CAP_SYS_RAWIO)) || (bdev != bdev->bd_contains)) - return -EPERM; - - idata = mmc_blk_ioctl_copy_from_user(ic_ptr); - if (IS_ERR(idata)) - return PTR_ERR(idata); - - md = mmc_blk_get(bdev->bd_disk); - if (!md) { - err = -EINVAL; - goto cmd_err; - } - - if (md->area_type & MMC_BLK_DATA_AREA_RPMB) - is_rpmb = true; - - card = md->queue.card; - if (IS_ERR(card)) { - err = PTR_ERR(card); - goto cmd_done; - } - - cmd.opcode = idata->ic.opcode; - cmd.arg = idata->ic.arg; - cmd.flags = idata->ic.flags; - - if (idata->buf_bytes) { - data.sg = &sg; - data.sg_len = 1; - data.blksz = idata->ic.blksz; - data.blocks = idata->ic.blocks; - - sg_init_one(data.sg, idata->buf, idata->buf_bytes); - - if (idata->ic.write_flag) - data.flags = MMC_DATA_WRITE; - else - data.flags = MMC_DATA_READ; - - /* data.flags must already be set before doing this. */ - mmc_set_data_timeout(&data, card); - - /* Allow overriding the timeout_ns for empirical tuning. */ - if (idata->ic.data_timeout_ns) - data.timeout_ns = idata->ic.data_timeout_ns; - - if ((cmd.flags & MMC_RSP_R1B) == MMC_RSP_R1B) { - /* - * Pretend this is a data transfer and rely on the - * host driver to compute timeout. When all host - * drivers support cmd.cmd_timeout for R1B, this - * can be changed to: - * - * mrq.data = NULL; - * cmd.cmd_timeout = idata->ic.cmd_timeout_ms; - */ - data.timeout_ns = idata->ic.cmd_timeout_ms * 1000000; - } - - mrq.data = &data; - } - - mrq.cmd = &cmd; - - mmc_get_card(card); - - err = mmc_blk_part_switch(card, md); - if (err) - goto cmd_rel_host; - - if (idata->ic.is_acmd) { - err = mmc_app_cmd(card->host, card); - if (err) - goto cmd_rel_host; - } - - if (is_rpmb) { - err = mmc_set_blockcount(card, data.blocks, - idata->ic.write_flag & (1 << 31)); - if (err) - goto cmd_rel_host; - } - - if ((MMC_EXTRACT_INDEX_FROM_ARG(cmd.arg) == EXT_CSD_SANITIZE_START) && - (cmd.opcode == MMC_SWITCH)) { - err = ioctl_do_sanitize(card); - - if (err) - pr_err("%s: ioctl_do_sanitize() failed. err = %d", - __func__, err); - - goto cmd_rel_host; - } - - mmc_wait_for_req(card->host, &mrq); - - if (cmd.error) { - dev_err(mmc_dev(card->host), "%s: cmd error %d\n", - __func__, cmd.error); - err = cmd.error; - goto cmd_rel_host; - } - if (data.error) { - dev_err(mmc_dev(card->host), "%s: data error %d\n", - __func__, data.error); - err = data.error; - goto cmd_rel_host; - } - - /* - * According to the SD specs, some commands require a delay after - * issuing the command. - */ - if (idata->ic.postsleep_min_us) - usleep_range(idata->ic.postsleep_min_us, idata->ic.postsleep_max_us); - - if (copy_to_user(&(ic_ptr->response), cmd.resp, sizeof(cmd.resp))) { - err = -EFAULT; - goto cmd_rel_host; - } - - if (!idata->ic.write_flag) { - if (copy_to_user((void __user *)(unsigned long) idata->ic.data_ptr, - idata->buf, idata->buf_bytes)) { - err = -EFAULT; - goto cmd_rel_host; - } - } - - if (is_rpmb) { - /* - * Ensure RPMB command has completed by polling CMD13 - * "Send Status". - */ - err = ioctl_rpmb_card_status_poll(card, &status, 5); - if (err) - dev_err(mmc_dev(card->host), - "%s: Card Status=0x%08X, error %d\n", - __func__, status, err); - } - -cmd_rel_host: - mmc_put_card(card); - -cmd_done: - mmc_blk_put(md); -cmd_err: - kfree(idata->buf); - kfree(idata); - return err; -} - -static int mmc_blk_ioctl(struct block_device *bdev, fmode_t mode, - unsigned int cmd, unsigned long arg) -{ - int ret = -EINVAL; - if (cmd == MMC_IOC_CMD) - ret = mmc_blk_ioctl_cmd(bdev, (struct mmc_ioc_cmd __user *)arg); - return ret; -} - -#ifdef CONFIG_COMPAT -static int mmc_blk_compat_ioctl(struct block_device *bdev, fmode_t mode, - unsigned int cmd, unsigned long arg) -{ - return mmc_blk_ioctl(bdev, mode, cmd, (unsigned long) compat_ptr(arg)); -} -#endif - -static const struct block_device_operations mmc_bdops = { - .open = mmc_blk_open, - .release = mmc_blk_release, - .getgeo = mmc_blk_getgeo, - .owner = THIS_MODULE, - .ioctl = mmc_blk_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = mmc_blk_compat_ioctl, -#endif -}; - -static inline int mmc_blk_part_switch(struct mmc_card *card, - struct mmc_blk_data *md) -{ - int ret; - struct mmc_blk_data *main_md = dev_get_drvdata(&card->dev); - - if (main_md->part_curr == md->part_type) - return 0; - - if (mmc_card_mmc(card)) { - u8 part_config = card->ext_csd.part_config; - - part_config &= ~EXT_CSD_PART_CONFIG_ACC_MASK; - part_config |= md->part_type; - - ret = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, - EXT_CSD_PART_CONFIG, part_config, - card->ext_csd.part_time); - if (ret) - return ret; - - card->ext_csd.part_config = part_config; - } - - main_md->part_curr = md->part_type; - return 0; -} - -static u32 mmc_sd_num_wr_blocks(struct mmc_card *card) -{ - int err; - u32 result; - __be32 *blocks; - - struct mmc_request mrq = {NULL}; - struct mmc_command cmd = {0}; - struct mmc_data data = {0}; - - struct scatterlist sg; - - cmd.opcode = MMC_APP_CMD; - cmd.arg = card->rca << 16; - cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC; - - err = mmc_wait_for_cmd(card->host, &cmd, 0); - if (err) - return (u32)-1; - if (!mmc_host_is_spi(card->host) && !(cmd.resp[0] & R1_APP_CMD)) - return (u32)-1; - - memset(&cmd, 0, sizeof(struct mmc_command)); - - cmd.opcode = SD_APP_SEND_NUM_WR_BLKS; - cmd.arg = 0; - cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC; - - data.blksz = 4; - data.blocks = 1; - data.flags = MMC_DATA_READ; - data.sg = &sg; - data.sg_len = 1; - mmc_set_data_timeout(&data, card); - - mrq.cmd = &cmd; - mrq.data = &data; - - blocks = kmalloc(4, GFP_KERNEL); - if (!blocks) - return (u32)-1; - - sg_init_one(&sg, blocks, 4); - - mmc_wait_for_req(card->host, &mrq); - - result = ntohl(*blocks); - kfree(blocks); - - if (cmd.error || data.error) - result = (u32)-1; - - return result; -} - -static int get_card_status(struct mmc_card *card, u32 *status, int retries) -{ - struct mmc_command cmd = {0}; - int err; - - cmd.opcode = MMC_SEND_STATUS; - if (!mmc_host_is_spi(card->host)) - cmd.arg = card->rca << 16; - cmd.flags = MMC_RSP_SPI_R2 | MMC_RSP_R1 | MMC_CMD_AC; - err = mmc_wait_for_cmd(card->host, &cmd, retries); - if (err == 0) - *status = cmd.resp[0]; - return err; -} - -static int card_busy_detect(struct mmc_card *card, unsigned int timeout_ms, - bool hw_busy_detect, struct request *req, int *gen_err) -{ - unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms); - int err = 0; - u32 status; - - do { - err = get_card_status(card, &status, 5); - if (err) { - pr_err("%s: error %d requesting status\n", - req->rq_disk->disk_name, err); - return err; - } - - if (status & R1_ERROR) { - pr_err("%s: %s: error sending status cmd, status %#x\n", - req->rq_disk->disk_name, __func__, status); - *gen_err = 1; - } - - /* We may rely on the host hw to handle busy detection.*/ - if ((card->host->caps & MMC_CAP_WAIT_WHILE_BUSY) && - hw_busy_detect) - break; - - /* - * Timeout if the device never becomes ready for data and never - * leaves the program state. - */ - if (time_after(jiffies, timeout)) { - pr_err("%s: Card stuck in programming state! %s %s\n", - mmc_hostname(card->host), - req->rq_disk->disk_name, __func__); - return -ETIMEDOUT; - } - - /* - * Some cards mishandle the status bits, - * so make sure to check both the busy - * indication and the card state. - */ - } while (!(status & R1_READY_FOR_DATA) || - (R1_CURRENT_STATE(status) == R1_STATE_PRG)); - - return err; -} - -static int send_stop(struct mmc_card *card, unsigned int timeout_ms, - struct request *req, int *gen_err, u32 *stop_status) -{ - struct mmc_host *host = card->host; - struct mmc_command cmd = {0}; - int err; - bool use_r1b_resp = rq_data_dir(req) == WRITE; - - /* - * Normally we use R1B responses for WRITE, but in cases where the host - * has specified a max_busy_timeout we need to validate it. A failure - * means we need to prevent the host from doing hw busy detection, which - * is done by converting to a R1 response instead. - */ - if (host->max_busy_timeout && (timeout_ms > host->max_busy_timeout)) - use_r1b_resp = false; - - cmd.opcode = MMC_STOP_TRANSMISSION; - if (use_r1b_resp) { - cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; - cmd.busy_timeout = timeout_ms; - } else { - cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC; - } - - err = mmc_wait_for_cmd(host, &cmd, 5); - if (err) - return err; - - *stop_status = cmd.resp[0]; - - /* No need to check card status in case of READ. */ - if (rq_data_dir(req) == READ) - return 0; - - if (!mmc_host_is_spi(host) && - (*stop_status & R1_ERROR)) { - pr_err("%s: %s: general error sending stop command, resp %#x\n", - req->rq_disk->disk_name, __func__, *stop_status); - *gen_err = 1; - } - - return card_busy_detect(card, timeout_ms, use_r1b_resp, req, gen_err); -} - -#define ERR_NOMEDIUM 3 -#define ERR_RETRY 2 -#define ERR_ABORT 1 -#define ERR_CONTINUE 0 - -static int mmc_blk_cmd_error(struct request *req, const char *name, int error, - bool status_valid, u32 status) -{ - switch (error) { - case -EILSEQ: - /* response crc error, retry the r/w cmd */ - pr_err("%s: %s sending %s command, card status %#x\n", - req->rq_disk->disk_name, "response CRC error", - name, status); - return ERR_RETRY; - - case -ETIMEDOUT: - pr_err("%s: %s sending %s command, card status %#x\n", - req->rq_disk->disk_name, "timed out", name, status); - - /* If the status cmd initially failed, retry the r/w cmd */ - if (!status_valid) - return ERR_RETRY; - - /* - * If it was a r/w cmd crc error, or illegal command - * (eg, issued in wrong state) then retry - we should - * have corrected the state problem above. - */ - if (status & (R1_COM_CRC_ERROR | R1_ILLEGAL_COMMAND)) - return ERR_RETRY; - - /* Otherwise abort the command */ - return ERR_ABORT; - - default: - /* We don't understand the error code the driver gave us */ - pr_err("%s: unknown error %d sending read/write command, card status %#x\n", - req->rq_disk->disk_name, error, status); - return ERR_ABORT; - } -} - -/* - * Initial r/w and stop cmd error recovery. - * We don't know whether the card received the r/w cmd or not, so try to - * restore things back to a sane state. Essentially, we do this as follows: - * - Obtain card status. If the first attempt to obtain card status fails, - * the status word will reflect the failed status cmd, not the failed - * r/w cmd. If we fail to obtain card status, it suggests we can no - * longer communicate with the card. - * - Check the card state. If the card received the cmd but there was a - * transient problem with the response, it might still be in a data transfer - * mode. Try to send it a stop command. If this fails, we can't recover. - * - If the r/w cmd failed due to a response CRC error, it was probably - * transient, so retry the cmd. - * - If the r/w cmd timed out, but we didn't get the r/w cmd status, retry. - * - If the r/w cmd timed out, and the r/w cmd failed due to CRC error or - * illegal cmd, retry. - * Otherwise we don't understand what happened, so abort. - */ -static int mmc_blk_cmd_recovery(struct mmc_card *card, struct request *req, - struct mmc_blk_request *brq, int *ecc_err, int *gen_err) -{ - bool prev_cmd_status_valid = true; - u32 status, stop_status = 0; - int err, retry; - - if (mmc_card_removed(card)) - return ERR_NOMEDIUM; - - /* - * Try to get card status which indicates both the card state - * and why there was no response. If the first attempt fails, - * we can't be sure the returned status is for the r/w command. - */ - for (retry = 2; retry >= 0; retry--) { - err = get_card_status(card, &status, 0); - if (!err) - break; - - prev_cmd_status_valid = false; - pr_err("%s: error %d sending status command, %sing\n", - req->rq_disk->disk_name, err, retry ? "retry" : "abort"); - } - - /* We couldn't get a response from the card. Give up. */ - if (err) { - /* Check if the card is removed */ - if (mmc_detect_card_removed(card->host)) - return ERR_NOMEDIUM; - return ERR_ABORT; - } - - /* Flag ECC errors */ - if ((status & R1_CARD_ECC_FAILED) || - (brq->stop.resp[0] & R1_CARD_ECC_FAILED) || - (brq->cmd.resp[0] & R1_CARD_ECC_FAILED)) - *ecc_err = 1; - - /* Flag General errors */ - if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) - if ((status & R1_ERROR) || - (brq->stop.resp[0] & R1_ERROR)) { - pr_err("%s: %s: general error sending stop or status command, stop cmd response %#x, card status %#x\n", - req->rq_disk->disk_name, __func__, - brq->stop.resp[0], status); - *gen_err = 1; - } - - /* - * Check the current card state. If it is in some data transfer - * mode, tell it to stop (and hopefully transition back to TRAN.) - */ - if (R1_CURRENT_STATE(status) == R1_STATE_DATA || - R1_CURRENT_STATE(status) == R1_STATE_RCV) { - err = send_stop(card, - DIV_ROUND_UP(brq->data.timeout_ns, 1000000), - req, gen_err, &stop_status); - if (err) { - pr_err("%s: error %d sending stop command\n", - req->rq_disk->disk_name, err); - /* - * If the stop cmd also timed out, the card is probably - * not present, so abort. Other errors are bad news too. - */ - return ERR_ABORT; - } - - if (stop_status & R1_CARD_ECC_FAILED) - *ecc_err = 1; - } - - /* Check for set block count errors */ - if (brq->sbc.error) - return mmc_blk_cmd_error(req, "SET_BLOCK_COUNT", brq->sbc.error, - prev_cmd_status_valid, status); - - /* Check for r/w command errors */ - if (brq->cmd.error) - return mmc_blk_cmd_error(req, "r/w cmd", brq->cmd.error, - prev_cmd_status_valid, status); - - /* Data errors */ - if (!brq->stop.error) - return ERR_CONTINUE; - - /* Now for stop errors. These aren't fatal to the transfer. */ - pr_info("%s: error %d sending stop command, original cmd response %#x, card status %#x\n", - req->rq_disk->disk_name, brq->stop.error, - brq->cmd.resp[0], status); - - /* - * Subsitute in our own stop status as this will give the error - * state which happened during the execution of the r/w command. - */ - if (stop_status) { - brq->stop.resp[0] = stop_status; - brq->stop.error = 0; - } - return ERR_CONTINUE; -} - -static int mmc_blk_reset(struct mmc_blk_data *md, struct mmc_host *host, - int type) -{ - int err; - - if (md->reset_done & type) - return -EEXIST; - - md->reset_done |= type; - err = mmc_hw_reset(host); - /* Ensure we switch back to the correct partition */ - if (err != -EOPNOTSUPP) { - struct mmc_blk_data *main_md = - dev_get_drvdata(&host->card->dev); - int part_err; - - main_md->part_curr = main_md->part_type; - part_err = mmc_blk_part_switch(host->card, md); - if (part_err) { - /* - * We have failed to get back into the correct - * partition, so we need to abort the whole request. - */ - return -ENODEV; - } - } - return err; -} - -static inline void mmc_blk_reset_success(struct mmc_blk_data *md, int type) -{ - md->reset_done &= ~type; -} - -int mmc_access_rpmb(struct mmc_queue *mq) -{ - struct mmc_blk_data *md = mq->data; - /* - * If this is a RPMB partition access, return ture - */ - if (md && md->part_type == EXT_CSD_PART_CONFIG_ACC_RPMB) - return true; - - return false; -} - -static int mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req) -{ - struct mmc_blk_data *md = mq->data; - struct mmc_card *card = md->queue.card; - unsigned int from, nr, arg; - int err = 0, type = MMC_BLK_DISCARD; - - if (!mmc_can_erase(card)) { - err = -EOPNOTSUPP; - goto out; - } - - from = blk_rq_pos(req); - nr = blk_rq_sectors(req); - - if (mmc_can_discard(card)) - arg = MMC_DISCARD_ARG; - else if (mmc_can_trim(card)) - arg = MMC_TRIM_ARG; - else - arg = MMC_ERASE_ARG; -retry: - if (card->quirks & MMC_QUIRK_INAND_CMD38) { - err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, - INAND_CMD38_ARG_EXT_CSD, - arg == MMC_TRIM_ARG ? - INAND_CMD38_ARG_TRIM : - INAND_CMD38_ARG_ERASE, - 0); - if (err) - goto out; - } - err = mmc_erase(card, from, nr, arg); -out: - if (err == -EIO && !mmc_blk_reset(md, card->host, type)) - goto retry; - if (!err) - mmc_blk_reset_success(md, type); - blk_end_request(req, err, blk_rq_bytes(req)); - - return err ? 0 : 1; -} - -static int mmc_blk_issue_secdiscard_rq(struct mmc_queue *mq, - struct request *req) -{ - struct mmc_blk_data *md = mq->data; - struct mmc_card *card = md->queue.card; - unsigned int from, nr, arg; - int err = 0, type = MMC_BLK_SECDISCARD; - - if (!(mmc_can_secure_erase_trim(card))) { - err = -EOPNOTSUPP; - goto out; - } - - from = blk_rq_pos(req); - nr = blk_rq_sectors(req); - - if (mmc_can_trim(card) && !mmc_erase_group_aligned(card, from, nr)) - arg = MMC_SECURE_TRIM1_ARG; - else - arg = MMC_SECURE_ERASE_ARG; - -retry: - if (card->quirks & MMC_QUIRK_INAND_CMD38) { - err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, - INAND_CMD38_ARG_EXT_CSD, - arg == MMC_SECURE_TRIM1_ARG ? - INAND_CMD38_ARG_SECTRIM1 : - INAND_CMD38_ARG_SECERASE, - 0); - if (err) - goto out_retry; - } - - err = mmc_erase(card, from, nr, arg); - if (err == -EIO) - goto out_retry; - if (err) - goto out; - - if (arg == MMC_SECURE_TRIM1_ARG) { - if (card->quirks & MMC_QUIRK_INAND_CMD38) { - err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, - INAND_CMD38_ARG_EXT_CSD, - INAND_CMD38_ARG_SECTRIM2, - 0); - if (err) - goto out_retry; - } - - err = mmc_erase(card, from, nr, MMC_SECURE_TRIM2_ARG); - if (err == -EIO) - goto out_retry; - if (err) - goto out; - } - -out_retry: - if (err && !mmc_blk_reset(md, card->host, type)) - goto retry; - if (!err) - mmc_blk_reset_success(md, type); -out: - blk_end_request(req, err, blk_rq_bytes(req)); - - return err ? 0 : 1; -} - -static int mmc_blk_issue_flush(struct mmc_queue *mq, struct request *req) -{ - struct mmc_blk_data *md = mq->data; - struct mmc_card *card = md->queue.card; - int ret = 0; - - ret = mmc_flush_cache(card); - if (ret) - ret = -EIO; - - blk_end_request_all(req, ret); - - return ret ? 0 : 1; -} - -/* - * Reformat current write as a reliable write, supporting - * both legacy and the enhanced reliable write MMC cards. - * In each transfer we'll handle only as much as a single - * reliable write can handle, thus finish the request in - * partial completions. - */ -static inline void mmc_apply_rel_rw(struct mmc_blk_request *brq, - struct mmc_card *card, - struct request *req) -{ - if (!(card->ext_csd.rel_param & EXT_CSD_WR_REL_PARAM_EN)) { - /* Legacy mode imposes restrictions on transfers. */ - if (!IS_ALIGNED(brq->cmd.arg, card->ext_csd.rel_sectors)) - brq->data.blocks = 1; - - if (brq->data.blocks > card->ext_csd.rel_sectors) - brq->data.blocks = card->ext_csd.rel_sectors; - else if (brq->data.blocks < card->ext_csd.rel_sectors) - brq->data.blocks = 1; - } -} - -#define CMD_ERRORS \ - (R1_OUT_OF_RANGE | /* Command argument out of range */ \ - R1_ADDRESS_ERROR | /* Misaligned address */ \ - R1_BLOCK_LEN_ERROR | /* Transferred block length incorrect */\ - R1_WP_VIOLATION | /* Tried to write to protected block */ \ - R1_CC_ERROR | /* Card controller error */ \ - R1_ERROR) /* General/unknown error */ - -static int mmc_blk_err_check(struct mmc_card *card, - struct mmc_async_req *areq) -{ - struct mmc_queue_req *mq_mrq = container_of(areq, struct mmc_queue_req, - mmc_active); - struct mmc_blk_request *brq = &mq_mrq->brq; - struct request *req = mq_mrq->req; - int ecc_err = 0, gen_err = 0; - - /* - * sbc.error indicates a problem with the set block count - * command. No data will have been transferred. - * - * cmd.error indicates a problem with the r/w command. No - * data will have been transferred. - * - * stop.error indicates a problem with the stop command. Data - * may have been transferred, or may still be transferring. - */ - if (brq->sbc.error || brq->cmd.error || brq->stop.error || - brq->data.error) { - switch (mmc_blk_cmd_recovery(card, req, brq, &ecc_err, &gen_err)) { - case ERR_RETRY: - return MMC_BLK_RETRY; - case ERR_ABORT: - return MMC_BLK_ABORT; - case ERR_NOMEDIUM: - return MMC_BLK_NOMEDIUM; - case ERR_CONTINUE: - break; - } - } - - /* - * Check for errors relating to the execution of the - * initial command - such as address errors. No data - * has been transferred. - */ - if (brq->cmd.resp[0] & CMD_ERRORS) { - pr_err("%s: r/w command failed, status = %#x\n", - req->rq_disk->disk_name, brq->cmd.resp[0]); - return MMC_BLK_ABORT; - } - - /* - * Everything else is either success, or a data error of some - * kind. If it was a write, we may have transitioned to - * program mode, which we have to wait for it to complete. - */ - if (!mmc_host_is_spi(card->host) && rq_data_dir(req) != READ) { - int err; - - /* Check stop command response */ - if (brq->stop.resp[0] & R1_ERROR) { - pr_err("%s: %s: general error sending stop command, stop cmd response %#x\n", - req->rq_disk->disk_name, __func__, - brq->stop.resp[0]); - gen_err = 1; - } - - err = card_busy_detect(card, MMC_BLK_TIMEOUT_MS, false, req, - &gen_err); - if (err) - return MMC_BLK_CMD_ERR; - } - - /* if general error occurs, retry the write operation. */ - if (gen_err) { - pr_warn("%s: retrying write for general error\n", - req->rq_disk->disk_name); - return MMC_BLK_RETRY; - } - - if (brq->data.error) { - pr_err("%s: error %d transferring data, sector %u, nr %u, cmd response %#x, card status %#x\n", - req->rq_disk->disk_name, brq->data.error, - (unsigned)blk_rq_pos(req), - (unsigned)blk_rq_sectors(req), - brq->cmd.resp[0], brq->stop.resp[0]); - - if (rq_data_dir(req) == READ) { - if (ecc_err) - return MMC_BLK_ECC_ERR; - return MMC_BLK_DATA_ERR; - } else { - return MMC_BLK_CMD_ERR; - } - } - - if (!brq->data.bytes_xfered) - return MMC_BLK_RETRY; - - if (mmc_packed_cmd(mq_mrq->cmd_type)) { - if (unlikely(brq->data.blocks << 9 != brq->data.bytes_xfered)) - return MMC_BLK_PARTIAL; - else - return MMC_BLK_SUCCESS; - } - - if (blk_rq_bytes(req) != brq->data.bytes_xfered) - return MMC_BLK_PARTIAL; - - return MMC_BLK_SUCCESS; -} - -static int mmc_blk_packed_err_check(struct mmc_card *card, - struct mmc_async_req *areq) -{ - struct mmc_queue_req *mq_rq = container_of(areq, struct mmc_queue_req, - mmc_active); - struct request *req = mq_rq->req; - struct mmc_packed *packed = mq_rq->packed; - int err, check, status; - u8 *ext_csd; - - BUG_ON(!packed); - - packed->retries--; - check = mmc_blk_err_check(card, areq); - err = get_card_status(card, &status, 0); - if (err) { - pr_err("%s: error %d sending status command\n", - req->rq_disk->disk_name, err); - return MMC_BLK_ABORT; - } - - if (status & R1_EXCEPTION_EVENT) { - err = mmc_get_ext_csd(card, &ext_csd); - if (err) { - pr_err("%s: error %d sending ext_csd\n", - req->rq_disk->disk_name, err); - return MMC_BLK_ABORT; - } - - if ((ext_csd[EXT_CSD_EXP_EVENTS_STATUS] & - EXT_CSD_PACKED_FAILURE) && - (ext_csd[EXT_CSD_PACKED_CMD_STATUS] & - EXT_CSD_PACKED_GENERIC_ERROR)) { - if (ext_csd[EXT_CSD_PACKED_CMD_STATUS] & - EXT_CSD_PACKED_INDEXED_ERROR) { - packed->idx_failure = - ext_csd[EXT_CSD_PACKED_FAILURE_INDEX] - 1; - check = MMC_BLK_PARTIAL; - } - pr_err("%s: packed cmd failed, nr %u, sectors %u, " - "failure index: %d\n", - req->rq_disk->disk_name, packed->nr_entries, - packed->blocks, packed->idx_failure); - } - kfree(ext_csd); - } - - return check; -} - -static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq, - struct mmc_card *card, - int disable_multi, - struct mmc_queue *mq) -{ - u32 readcmd, writecmd; - struct mmc_blk_request *brq = &mqrq->brq; - struct request *req = mqrq->req; - struct mmc_blk_data *md = mq->data; - bool do_data_tag; - - /* - * Reliable writes are used to implement Forced Unit Access and - * REQ_META accesses, and are supported only on MMCs. - * - * XXX: this really needs a good explanation of why REQ_META - * is treated special. - */ - bool do_rel_wr = ((req->cmd_flags & REQ_FUA) || - (req->cmd_flags & REQ_META)) && - (rq_data_dir(req) == WRITE) && - (md->flags & MMC_BLK_REL_WR); - - memset(brq, 0, sizeof(struct mmc_blk_request)); - brq->mrq.cmd = &brq->cmd; - brq->mrq.data = &brq->data; - - brq->cmd.arg = blk_rq_pos(req); - if (!mmc_card_blockaddr(card)) - brq->cmd.arg <<= 9; - brq->cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC; - brq->data.blksz = 512; - brq->stop.opcode = MMC_STOP_TRANSMISSION; - brq->stop.arg = 0; - brq->data.blocks = blk_rq_sectors(req); - - /* - * The block layer doesn't support all sector count - * restrictions, so we need to be prepared for too big - * requests. - */ - if (brq->data.blocks > card->host->max_blk_count) - brq->data.blocks = card->host->max_blk_count; - - if (brq->data.blocks > 1) { - /* - * After a read error, we redo the request one sector - * at a time in order to accurately determine which - * sectors can be read successfully. - */ - if (disable_multi) - brq->data.blocks = 1; - - /* - * Some controllers have HW issues while operating - * in multiple I/O mode - */ - if (card->host->ops->multi_io_quirk) - brq->data.blocks = card->host->ops->multi_io_quirk(card, - (rq_data_dir(req) == READ) ? - MMC_DATA_READ : MMC_DATA_WRITE, - brq->data.blocks); - } - - if (brq->data.blocks > 1 || do_rel_wr) { - /* SPI multiblock writes terminate using a special - * token, not a STOP_TRANSMISSION request. - */ - if (!mmc_host_is_spi(card->host) || - rq_data_dir(req) == READ) - brq->mrq.stop = &brq->stop; - readcmd = MMC_READ_MULTIPLE_BLOCK; - writecmd = MMC_WRITE_MULTIPLE_BLOCK; - } else { - brq->mrq.stop = NULL; - readcmd = MMC_READ_SINGLE_BLOCK; - writecmd = MMC_WRITE_BLOCK; - } - if (rq_data_dir(req) == READ) { - brq->cmd.opcode = readcmd; - brq->data.flags |= MMC_DATA_READ; - if (brq->mrq.stop) - brq->stop.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | - MMC_CMD_AC; - } else { - brq->cmd.opcode = writecmd; - brq->data.flags |= MMC_DATA_WRITE; - if (brq->mrq.stop) - brq->stop.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | - MMC_CMD_AC; - } - - if (do_rel_wr) - mmc_apply_rel_rw(brq, card, req); - - /* - * Data tag is used only during writing meta data to speed - * up write and any subsequent read of this meta data - */ - do_data_tag = (card->ext_csd.data_tag_unit_size) && - (req->cmd_flags & REQ_META) && - (rq_data_dir(req) == WRITE) && - ((brq->data.blocks * brq->data.blksz) >= - card->ext_csd.data_tag_unit_size); - - /* - * Pre-defined multi-block transfers are preferable to - * open ended-ones (and necessary for reliable writes). - * However, it is not sufficient to just send CMD23, - * and avoid the final CMD12, as on an error condition - * CMD12 (stop) needs to be sent anyway. This, coupled - * with Auto-CMD23 enhancements provided by some - * hosts, means that the complexity of dealing - * with this is best left to the host. If CMD23 is - * supported by card and host, we'll fill sbc in and let - * the host deal with handling it correctly. This means - * that for hosts that don't expose MMC_CAP_CMD23, no - * change of behavior will be observed. - * - * N.B: Some MMC cards experience perf degradation. - * We'll avoid using CMD23-bounded multiblock writes for - * these, while retaining features like reliable writes. - */ - if ((md->flags & MMC_BLK_CMD23) && mmc_op_multi(brq->cmd.opcode) && - (do_rel_wr || !(card->quirks & MMC_QUIRK_BLK_NO_CMD23) || - do_data_tag)) { - brq->sbc.opcode = MMC_SET_BLOCK_COUNT; - brq->sbc.arg = brq->data.blocks | - (do_rel_wr ? (1 << 31) : 0) | - (do_data_tag ? (1 << 29) : 0); - brq->sbc.flags = MMC_RSP_R1 | MMC_CMD_AC; - brq->mrq.sbc = &brq->sbc; - } - - mmc_set_data_timeout(&brq->data, card); - - brq->data.sg = mqrq->sg; - brq->data.sg_len = mmc_queue_map_sg(mq, mqrq); - - /* - * Adjust the sg list so it is the same size as the - * request. - */ - if (brq->data.blocks != blk_rq_sectors(req)) { - int i, data_size = brq->data.blocks << 9; - struct scatterlist *sg; - - for_each_sg(brq->data.sg, sg, brq->data.sg_len, i) { - data_size -= sg->length; - if (data_size <= 0) { - sg->length += data_size; - i++; - break; - } - } - brq->data.sg_len = i; - } - - mqrq->mmc_active.mrq = &brq->mrq; - mqrq->mmc_active.err_check = mmc_blk_err_check; - - mmc_queue_bounce_pre(mqrq); -} - -static inline u8 mmc_calc_packed_hdr_segs(struct request_queue *q, - struct mmc_card *card) -{ - unsigned int hdr_sz = mmc_large_sector(card) ? 4096 : 512; - unsigned int max_seg_sz = queue_max_segment_size(q); - unsigned int len, nr_segs = 0; - - do { - len = min(hdr_sz, max_seg_sz); - hdr_sz -= len; - nr_segs++; - } while (hdr_sz); - - return nr_segs; -} - -static u8 mmc_blk_prep_packed_list(struct mmc_queue *mq, struct request *req) -{ - struct request_queue *q = mq->queue; - struct mmc_card *card = mq->card; - struct request *cur = req, *next = NULL; - struct mmc_blk_data *md = mq->data; - struct mmc_queue_req *mqrq = mq->mqrq_cur; - bool en_rel_wr = card->ext_csd.rel_param & EXT_CSD_WR_REL_PARAM_EN; - unsigned int req_sectors = 0, phys_segments = 0; - unsigned int max_blk_count, max_phys_segs; - bool put_back = true; - u8 max_packed_rw = 0; - u8 reqs = 0; - - if (!(md->flags & MMC_BLK_PACKED_CMD)) - goto no_packed; - - if ((rq_data_dir(cur) == WRITE) && - mmc_host_packed_wr(card->host)) - max_packed_rw = card->ext_csd.max_packed_writes; - - if (max_packed_rw == 0) - goto no_packed; - - if (mmc_req_rel_wr(cur) && - (md->flags & MMC_BLK_REL_WR) && !en_rel_wr) - goto no_packed; - - if (mmc_large_sector(card) && - !IS_ALIGNED(blk_rq_sectors(cur), 8)) - goto no_packed; - - mmc_blk_clear_packed(mqrq); - - max_blk_count = min(card->host->max_blk_count, - card->host->max_req_size >> 9); - if (unlikely(max_blk_count > 0xffff)) - max_blk_count = 0xffff; - - max_phys_segs = queue_max_segments(q); - req_sectors += blk_rq_sectors(cur); - phys_segments += cur->nr_phys_segments; - - if (rq_data_dir(cur) == WRITE) { - req_sectors += mmc_large_sector(card) ? 8 : 1; - phys_segments += mmc_calc_packed_hdr_segs(q, card); - } - - do { - if (reqs >= max_packed_rw - 1) { - put_back = false; - break; - } - - spin_lock_irq(q->queue_lock); - next = blk_fetch_request(q); - spin_unlock_irq(q->queue_lock); - if (!next) { - put_back = false; - break; - } - - if (mmc_large_sector(card) && - !IS_ALIGNED(blk_rq_sectors(next), 8)) - break; - - if (next->cmd_flags & REQ_DISCARD || - next->cmd_flags & REQ_FLUSH) - break; - - if (rq_data_dir(cur) != rq_data_dir(next)) - break; - - if (mmc_req_rel_wr(next) && - (md->flags & MMC_BLK_REL_WR) && !en_rel_wr) - break; - - req_sectors += blk_rq_sectors(next); - if (req_sectors > max_blk_count) - break; - - phys_segments += next->nr_phys_segments; - if (phys_segments > max_phys_segs) - break; - - list_add_tail(&next->queuelist, &mqrq->packed->list); - cur = next; - reqs++; - } while (1); - - if (put_back) { - spin_lock_irq(q->queue_lock); - blk_requeue_request(q, next); - spin_unlock_irq(q->queue_lock); - } - - if (reqs > 0) { - list_add(&req->queuelist, &mqrq->packed->list); - mqrq->packed->nr_entries = ++reqs; - mqrq->packed->retries = reqs; - return reqs; - } - -no_packed: - mqrq->cmd_type = MMC_PACKED_NONE; - return 0; -} - -static void mmc_blk_packed_hdr_wrq_prep(struct mmc_queue_req *mqrq, - struct mmc_card *card, - struct mmc_queue *mq) -{ - struct mmc_blk_request *brq = &mqrq->brq; - struct request *req = mqrq->req; - struct request *prq; - struct mmc_blk_data *md = mq->data; - struct mmc_packed *packed = mqrq->packed; - bool do_rel_wr, do_data_tag; - u32 *packed_cmd_hdr; - u8 hdr_blocks; - u8 i = 1; - - BUG_ON(!packed); - - mqrq->cmd_type = MMC_PACKED_WRITE; - packed->blocks = 0; - packed->idx_failure = MMC_PACKED_NR_IDX; - - packed_cmd_hdr = packed->cmd_hdr; - memset(packed_cmd_hdr, 0, sizeof(packed->cmd_hdr)); - packed_cmd_hdr[0] = (packed->nr_entries << 16) | - (PACKED_CMD_WR << 8) | PACKED_CMD_VER; - hdr_blocks = mmc_large_sector(card) ? 8 : 1; - - /* - * Argument for each entry of packed group - */ - list_for_each_entry(prq, &packed->list, queuelist) { - do_rel_wr = mmc_req_rel_wr(prq) && (md->flags & MMC_BLK_REL_WR); - do_data_tag = (card->ext_csd.data_tag_unit_size) && - (prq->cmd_flags & REQ_META) && - (rq_data_dir(prq) == WRITE) && - ((brq->data.blocks * brq->data.blksz) >= - card->ext_csd.data_tag_unit_size); - /* Argument of CMD23 */ - packed_cmd_hdr[(i * 2)] = - (do_rel_wr ? MMC_CMD23_ARG_REL_WR : 0) | - (do_data_tag ? MMC_CMD23_ARG_TAG_REQ : 0) | - blk_rq_sectors(prq); - /* Argument of CMD18 or CMD25 */ - packed_cmd_hdr[((i * 2)) + 1] = - mmc_card_blockaddr(card) ? - blk_rq_pos(prq) : blk_rq_pos(prq) << 9; - packed->blocks += blk_rq_sectors(prq); - i++; - } - - memset(brq, 0, sizeof(struct mmc_blk_request)); - brq->mrq.cmd = &brq->cmd; - brq->mrq.data = &brq->data; - brq->mrq.sbc = &brq->sbc; - brq->mrq.stop = &brq->stop; - - brq->sbc.opcode = MMC_SET_BLOCK_COUNT; - brq->sbc.arg = MMC_CMD23_ARG_PACKED | (packed->blocks + hdr_blocks); - brq->sbc.flags = MMC_RSP_R1 | MMC_CMD_AC; - - brq->cmd.opcode = MMC_WRITE_MULTIPLE_BLOCK; - brq->cmd.arg = blk_rq_pos(req); - if (!mmc_card_blockaddr(card)) - brq->cmd.arg <<= 9; - brq->cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC; - - brq->data.blksz = 512; - brq->data.blocks = packed->blocks + hdr_blocks; - brq->data.flags |= MMC_DATA_WRITE; - - brq->stop.opcode = MMC_STOP_TRANSMISSION; - brq->stop.arg = 0; - brq->stop.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC; - - mmc_set_data_timeout(&brq->data, card); - - brq->data.sg = mqrq->sg; - brq->data.sg_len = mmc_queue_map_sg(mq, mqrq); - - mqrq->mmc_active.mrq = &brq->mrq; - mqrq->mmc_active.err_check = mmc_blk_packed_err_check; - - mmc_queue_bounce_pre(mqrq); -} - -static int mmc_blk_cmd_err(struct mmc_blk_data *md, struct mmc_card *card, - struct mmc_blk_request *brq, struct request *req, - int ret) -{ - struct mmc_queue_req *mq_rq; - mq_rq = container_of(brq, struct mmc_queue_req, brq); - - /* - * If this is an SD card and we're writing, we can first - * mark the known good sectors as ok. - * - * If the card is not SD, we can still ok written sectors - * as reported by the controller (which might be less than - * the real number of written sectors, but never more). - */ - if (mmc_card_sd(card)) { - u32 blocks; - - blocks = mmc_sd_num_wr_blocks(card); - if (blocks != (u32)-1) { - ret = blk_end_request(req, 0, blocks << 9); - } - } else { - if (!mmc_packed_cmd(mq_rq->cmd_type)) - ret = blk_end_request(req, 0, brq->data.bytes_xfered); - } - return ret; -} - -static int mmc_blk_end_packed_req(struct mmc_queue_req *mq_rq) -{ - struct request *prq; - struct mmc_packed *packed = mq_rq->packed; - int idx = packed->idx_failure, i = 0; - int ret = 0; - - BUG_ON(!packed); - - while (!list_empty(&packed->list)) { - prq = list_entry_rq(packed->list.next); - if (idx == i) { - /* retry from error index */ - packed->nr_entries -= idx; - mq_rq->req = prq; - ret = 1; - - if (packed->nr_entries == MMC_PACKED_NR_SINGLE) { - list_del_init(&prq->queuelist); - mmc_blk_clear_packed(mq_rq); - } - return ret; - } - list_del_init(&prq->queuelist); - blk_end_request(prq, 0, blk_rq_bytes(prq)); - i++; - } - - mmc_blk_clear_packed(mq_rq); - return ret; -} - -static void mmc_blk_abort_packed_req(struct mmc_queue_req *mq_rq) -{ - struct request *prq; - struct mmc_packed *packed = mq_rq->packed; - - BUG_ON(!packed); - - while (!list_empty(&packed->list)) { - prq = list_entry_rq(packed->list.next); - list_del_init(&prq->queuelist); - blk_end_request(prq, -EIO, blk_rq_bytes(prq)); - } - - mmc_blk_clear_packed(mq_rq); -} - -static void mmc_blk_revert_packed_req(struct mmc_queue *mq, - struct mmc_queue_req *mq_rq) -{ - struct request *prq; - struct request_queue *q = mq->queue; - struct mmc_packed *packed = mq_rq->packed; - - BUG_ON(!packed); - - while (!list_empty(&packed->list)) { - prq = list_entry_rq(packed->list.prev); - if (prq->queuelist.prev != &packed->list) { - list_del_init(&prq->queuelist); - spin_lock_irq(q->queue_lock); - blk_requeue_request(mq->queue, prq); - spin_unlock_irq(q->queue_lock); - } else { - list_del_init(&prq->queuelist); - } - } - - mmc_blk_clear_packed(mq_rq); -} - -static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc) -{ - struct mmc_blk_data *md = mq->data; - struct mmc_card *card = md->queue.card; - struct mmc_blk_request *brq = &mq->mqrq_cur->brq; - int ret = 1, disable_multi = 0, retry = 0, type; - enum mmc_blk_status status; - struct mmc_queue_req *mq_rq; - struct request *req = rqc; - struct mmc_async_req *areq; - const u8 packed_nr = 2; - u8 reqs = 0; - - if (!rqc && !mq->mqrq_prev->req) - return 0; - - if (rqc) - reqs = mmc_blk_prep_packed_list(mq, rqc); - - do { - if (rqc) { - /* - * When 4KB native sector is enabled, only 8 blocks - * multiple read or write is allowed - */ - if ((brq->data.blocks & 0x07) && - (card->ext_csd.data_sector_size == 4096)) { - pr_err("%s: Transfer size is not 4KB sector size aligned\n", - req->rq_disk->disk_name); - mq_rq = mq->mqrq_cur; - goto cmd_abort; - } - - if (reqs >= packed_nr) - mmc_blk_packed_hdr_wrq_prep(mq->mqrq_cur, - card, mq); - else - mmc_blk_rw_rq_prep(mq->mqrq_cur, card, 0, mq); - areq = &mq->mqrq_cur->mmc_active; - } else - areq = NULL; - areq = mmc_start_req(card->host, areq, (int *) &status); - if (!areq) { - if (status == MMC_BLK_NEW_REQUEST) - mq->flags |= MMC_QUEUE_NEW_REQUEST; - return 0; - } - - mq_rq = container_of(areq, struct mmc_queue_req, mmc_active); - brq = &mq_rq->brq; - req = mq_rq->req; - type = rq_data_dir(req) == READ ? MMC_BLK_READ : MMC_BLK_WRITE; - mmc_queue_bounce_post(mq_rq); - - switch (status) { - case MMC_BLK_SUCCESS: - case MMC_BLK_PARTIAL: - /* - * A block was successfully transferred. - */ - mmc_blk_reset_success(md, type); - - if (mmc_packed_cmd(mq_rq->cmd_type)) { - ret = mmc_blk_end_packed_req(mq_rq); - break; - } else { - ret = blk_end_request(req, 0, - brq->data.bytes_xfered); - } - - /* - * If the blk_end_request function returns non-zero even - * though all data has been transferred and no errors - * were returned by the host controller, it's a bug. - */ - if (status == MMC_BLK_SUCCESS && ret) { - pr_err("%s BUG rq_tot %d d_xfer %d\n", - __func__, blk_rq_bytes(req), - brq->data.bytes_xfered); - rqc = NULL; - goto cmd_abort; - } - break; - case MMC_BLK_CMD_ERR: - ret = mmc_blk_cmd_err(md, card, brq, req, ret); - if (mmc_blk_reset(md, card->host, type)) - goto cmd_abort; - if (!ret) - goto start_new_req; - break; - case MMC_BLK_RETRY: - if (retry++ < 5) - break; - /* Fall through */ - case MMC_BLK_ABORT: - if (!mmc_blk_reset(md, card->host, type)) - break; - goto cmd_abort; - case MMC_BLK_DATA_ERR: { - int err; - - err = mmc_blk_reset(md, card->host, type); - if (!err) - break; - if (err == -ENODEV || - mmc_packed_cmd(mq_rq->cmd_type)) - goto cmd_abort; - /* Fall through */ - } - case MMC_BLK_ECC_ERR: - if (brq->data.blocks > 1) { - /* Redo read one sector at a time */ - pr_warn("%s: retrying using single block read\n", - req->rq_disk->disk_name); - disable_multi = 1; - break; - } - /* - * After an error, we redo I/O one sector at a - * time, so we only reach here after trying to - * read a single sector. - */ - ret = blk_end_request(req, -EIO, - brq->data.blksz); - if (!ret) - goto start_new_req; - break; - case MMC_BLK_NOMEDIUM: - goto cmd_abort; - default: - pr_err("%s: Unhandled return value (%d)", - req->rq_disk->disk_name, status); - goto cmd_abort; - } - - if (ret) { - if (mmc_packed_cmd(mq_rq->cmd_type)) { - if (!mq_rq->packed->retries) - goto cmd_abort; - mmc_blk_packed_hdr_wrq_prep(mq_rq, card, mq); - mmc_start_req(card->host, - &mq_rq->mmc_active, NULL); - } else { - - /* - * In case of a incomplete request - * prepare it again and resend. - */ - mmc_blk_rw_rq_prep(mq_rq, card, - disable_multi, mq); - mmc_start_req(card->host, - &mq_rq->mmc_active, NULL); - } - } - } while (ret); - - return 1; - - cmd_abort: - if (mmc_packed_cmd(mq_rq->cmd_type)) { - mmc_blk_abort_packed_req(mq_rq); - } else { - if (mmc_card_removed(card)) - req->cmd_flags |= REQ_QUIET; - while (ret) - ret = blk_end_request(req, -EIO, - blk_rq_cur_bytes(req)); - } - - start_new_req: - if (rqc) { - if (mmc_card_removed(card)) { - rqc->cmd_flags |= REQ_QUIET; - blk_end_request_all(rqc, -EIO); - } else { - /* - * If current request is packed, it needs to put back. - */ - if (mmc_packed_cmd(mq->mqrq_cur->cmd_type)) - mmc_blk_revert_packed_req(mq, mq->mqrq_cur); - - mmc_blk_rw_rq_prep(mq->mqrq_cur, card, 0, mq); - mmc_start_req(card->host, - &mq->mqrq_cur->mmc_active, NULL); - } - } - - return 0; -} - -static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) -{ - int ret; - struct mmc_blk_data *md = mq->data; - struct mmc_card *card = md->queue.card; - struct mmc_host *host = card->host; - unsigned long flags; - unsigned int cmd_flags = req ? req->cmd_flags : 0; - - if (req && !mq->mqrq_prev->req) - /* claim host only for the first request */ - mmc_get_card(card); - - ret = mmc_blk_part_switch(card, md); - if (ret) { - if (req) { - blk_end_request_all(req, -EIO); - } - ret = 0; - goto out; - } - - mq->flags &= ~MMC_QUEUE_NEW_REQUEST; - if (cmd_flags & REQ_DISCARD) { - /* complete ongoing async transfer before issuing discard */ - if (card->host->areq) - mmc_blk_issue_rw_rq(mq, NULL); - if (req->cmd_flags & REQ_SECURE) - ret = mmc_blk_issue_secdiscard_rq(mq, req); - else - ret = mmc_blk_issue_discard_rq(mq, req); - } else if (cmd_flags & REQ_FLUSH) { - /* complete ongoing async transfer before issuing flush */ - if (card->host->areq) - mmc_blk_issue_rw_rq(mq, NULL); - ret = mmc_blk_issue_flush(mq, req); - } else { - if (!req && host->areq) { - spin_lock_irqsave(&host->context_info.lock, flags); - host->context_info.is_waiting_last_req = true; - spin_unlock_irqrestore(&host->context_info.lock, flags); - } - ret = mmc_blk_issue_rw_rq(mq, req); - } - -out: - if ((!req && !(mq->flags & MMC_QUEUE_NEW_REQUEST)) || - (cmd_flags & MMC_REQ_SPECIAL_MASK)) - /* - * Release host when there are no more requests - * and after special request(discard, flush) is done. - * In case sepecial request, there is no reentry to - * the 'mmc_blk_issue_rq' with 'mqrq_prev->req'. - */ - mmc_put_card(card); - return ret; -} - -static inline int mmc_blk_readonly(struct mmc_card *card) -{ - return mmc_card_readonly(card) || - !(card->csd.cmdclass & CCC_BLOCK_WRITE); -} - -static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card, - struct device *parent, - sector_t size, - bool default_ro, - const char *subname, - int area_type) -{ - struct mmc_blk_data *md; - int devidx, ret; - - devidx = find_first_zero_bit(dev_use, max_devices); - if (devidx >= max_devices) - return ERR_PTR(-ENOSPC); - __set_bit(devidx, dev_use); - - md = kzalloc(sizeof(struct mmc_blk_data), GFP_KERNEL); - if (!md) { - ret = -ENOMEM; - goto out; - } - - /* - * !subname implies we are creating main mmc_blk_data that will be - * associated with mmc_card with dev_set_drvdata. Due to device - * partitions, devidx will not coincide with a per-physical card - * index anymore so we keep track of a name index. - */ - if (!subname) { - md->name_idx = find_first_zero_bit(name_use, max_devices); - __set_bit(md->name_idx, name_use); - } else - md->name_idx = ((struct mmc_blk_data *) - dev_to_disk(parent)->private_data)->name_idx; - - md->area_type = area_type; - - /* - * Set the read-only status based on the supported commands - * and the write protect switch. - */ - md->read_only = mmc_blk_readonly(card); - - md->disk = alloc_disk(perdev_minors); - if (md->disk == NULL) { - ret = -ENOMEM; - goto err_kfree; - } - - spin_lock_init(&md->lock); - INIT_LIST_HEAD(&md->part); - md->usage = 1; - - ret = mmc_init_queue(&md->queue, card, &md->lock, subname); - if (ret) - goto err_putdisk; - - md->queue.issue_fn = mmc_blk_issue_rq; - md->queue.data = md; - - md->disk->major = MMC_BLOCK_MAJOR; - md->disk->first_minor = devidx * perdev_minors; - md->disk->fops = &mmc_bdops; - md->disk->private_data = md; - md->disk->queue = md->queue.queue; - md->disk->driverfs_dev = parent; - set_disk_ro(md->disk, md->read_only || default_ro); - if (area_type & (MMC_BLK_DATA_AREA_RPMB | MMC_BLK_DATA_AREA_BOOT)) - md->disk->flags |= GENHD_FL_NO_PART_SCAN; - - /* - * As discussed on lkml, GENHD_FL_REMOVABLE should: - * - * - be set for removable media with permanent block devices - * - be unset for removable block devices with permanent media - * - * Since MMC block devices clearly fall under the second - * case, we do not set GENHD_FL_REMOVABLE. Userspace - * should use the block device creation/destruction hotplug - * messages to tell when the card is present. - */ - - snprintf(md->disk->disk_name, sizeof(md->disk->disk_name), - "mmcblk%u%s", md->name_idx, subname ? subname : ""); - - if (mmc_card_mmc(card)) - blk_queue_logical_block_size(md->queue.queue, - card->ext_csd.data_sector_size); - else - blk_queue_logical_block_size(md->queue.queue, 512); - - set_capacity(md->disk, size); - - if (mmc_host_cmd23(card->host)) { - if (mmc_card_mmc(card) || - (mmc_card_sd(card) && - card->scr.cmds & SD_SCR_CMD23_SUPPORT)) - md->flags |= MMC_BLK_CMD23; - } - - if (mmc_card_mmc(card) && - md->flags & MMC_BLK_CMD23 && - ((card->ext_csd.rel_param & EXT_CSD_WR_REL_PARAM_EN) || - card->ext_csd.rel_sectors)) { - md->flags |= MMC_BLK_REL_WR; - blk_queue_flush(md->queue.queue, REQ_FLUSH | REQ_FUA); - } - - if (mmc_card_mmc(card) && - (area_type == MMC_BLK_DATA_AREA_MAIN) && - (md->flags & MMC_BLK_CMD23) && - card->ext_csd.packed_event_en) { - if (!mmc_packed_init(&md->queue, card)) - md->flags |= MMC_BLK_PACKED_CMD; - } - - return md; - - err_putdisk: - put_disk(md->disk); - err_kfree: - kfree(md); - out: - return ERR_PTR(ret); -} - -static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) -{ - sector_t size; - - if (!mmc_card_sd(card) && mmc_card_blockaddr(card)) { - /* - * The EXT_CSD sector count is in number or 512 byte - * sectors. - */ - size = card->ext_csd.sectors; - } else { - /* - * The CSD capacity field is in units of read_blkbits. - * set_capacity takes units of 512 bytes. - */ - size = card->csd.capacity << (card->csd.read_blkbits - 9); - } - - return mmc_blk_alloc_req(card, &card->dev, size, false, NULL, - MMC_BLK_DATA_AREA_MAIN); -} - -static int mmc_blk_alloc_part(struct mmc_card *card, - struct mmc_blk_data *md, - unsigned int part_type, - sector_t size, - bool default_ro, - const char *subname, - int area_type) -{ - char cap_str[10]; - struct mmc_blk_data *part_md; - - part_md = mmc_blk_alloc_req(card, disk_to_dev(md->disk), size, default_ro, - subname, area_type); - if (IS_ERR(part_md)) - return PTR_ERR(part_md); - part_md->part_type = part_type; - list_add(&part_md->part, &md->part); - - string_get_size((u64)get_capacity(part_md->disk), 512, STRING_UNITS_2, - cap_str, sizeof(cap_str)); - pr_info("%s: %s %s partition %u %s\n", - part_md->disk->disk_name, mmc_card_id(card), - mmc_card_name(card), part_md->part_type, cap_str); - return 0; -} - -/* MMC Physical partitions consist of two boot partitions and - * up to four general purpose partitions. - * For each partition enabled in EXT_CSD a block device will be allocatedi - * to provide access to the partition. - */ - -static int mmc_blk_alloc_parts(struct mmc_card *card, struct mmc_blk_data *md) -{ - int idx, ret = 0; - - if (!mmc_card_mmc(card)) - return 0; - -#if !defined (POLEG_DRB_HW) - pr_info("%s(): MMC_BLK_DATA_AREA_RPMB workaround\n", __func__); -#endif - for (idx = 0; idx < card->nr_parts; idx++) { -#if !defined (POLEG_DRB_HW) - if (card->part[idx].size && !(card->part[idx].area_type & MMC_BLK_DATA_AREA_RPMB)) { -#else - if (card->part[idx].size) { -#endif - ret = mmc_blk_alloc_part(card, md, - card->part[idx].part_cfg, - card->part[idx].size >> 9, - card->part[idx].force_ro, - card->part[idx].name, - card->part[idx].area_type); - if (ret) - return ret; - } - } - - return ret; -} - -static void mmc_blk_remove_req(struct mmc_blk_data *md) -{ - struct mmc_card *card; - - if (md) { - /* - * Flush remaining requests and free queues. It - * is freeing the queue that stops new requests - * from being accepted. - */ - card = md->queue.card; - mmc_cleanup_queue(&md->queue); - if (md->flags & MMC_BLK_PACKED_CMD) - mmc_packed_clean(&md->queue); - if (md->disk->flags & GENHD_FL_UP) { - device_remove_file(disk_to_dev(md->disk), &md->force_ro); - if ((md->area_type & MMC_BLK_DATA_AREA_BOOT) && - card->ext_csd.boot_ro_lockable) - device_remove_file(disk_to_dev(md->disk), - &md->power_ro_lock); - - del_gendisk(md->disk); - } - mmc_blk_put(md); - } -} - -static void mmc_blk_remove_parts(struct mmc_card *card, - struct mmc_blk_data *md) -{ - struct list_head *pos, *q; - struct mmc_blk_data *part_md; - - __clear_bit(md->name_idx, name_use); - list_for_each_safe(pos, q, &md->part) { - part_md = list_entry(pos, struct mmc_blk_data, part); - list_del(pos); - mmc_blk_remove_req(part_md); - } -} - -static int mmc_add_disk(struct mmc_blk_data *md) -{ - int ret; - struct mmc_card *card = md->queue.card; - - add_disk(md->disk); - md->force_ro.show = force_ro_show; - md->force_ro.store = force_ro_store; - sysfs_attr_init(&md->force_ro.attr); - md->force_ro.attr.name = "force_ro"; - md->force_ro.attr.mode = S_IRUGO | S_IWUSR; - ret = device_create_file(disk_to_dev(md->disk), &md->force_ro); - if (ret) - goto force_ro_fail; - - if ((md->area_type & MMC_BLK_DATA_AREA_BOOT) && - card->ext_csd.boot_ro_lockable) { - umode_t mode; - - if (card->ext_csd.boot_ro_lock & EXT_CSD_BOOT_WP_B_PWR_WP_DIS) - mode = S_IRUGO; - else - mode = S_IRUGO | S_IWUSR; - - md->power_ro_lock.show = power_ro_lock_show; - md->power_ro_lock.store = power_ro_lock_store; - sysfs_attr_init(&md->power_ro_lock.attr); - md->power_ro_lock.attr.mode = mode; - md->power_ro_lock.attr.name = - "ro_lock_until_next_power_on"; - ret = device_create_file(disk_to_dev(md->disk), - &md->power_ro_lock); - if (ret) - goto power_ro_lock_fail; - } - return ret; - -power_ro_lock_fail: - device_remove_file(disk_to_dev(md->disk), &md->force_ro); -force_ro_fail: - del_gendisk(md->disk); - - return ret; -} - -#define CID_MANFID_SANDISK 0x2 -#define CID_MANFID_TOSHIBA 0x11 -#define CID_MANFID_MICRON 0x13 -#define CID_MANFID_SAMSUNG 0x15 - -static const struct mmc_fixup blk_fixups[] = -{ - MMC_FIXUP("SEM02G", CID_MANFID_SANDISK, 0x100, add_quirk, - MMC_QUIRK_INAND_CMD38), - MMC_FIXUP("SEM04G", CID_MANFID_SANDISK, 0x100, add_quirk, - MMC_QUIRK_INAND_CMD38), - MMC_FIXUP("SEM08G", CID_MANFID_SANDISK, 0x100, add_quirk, - MMC_QUIRK_INAND_CMD38), - MMC_FIXUP("SEM16G", CID_MANFID_SANDISK, 0x100, add_quirk, - MMC_QUIRK_INAND_CMD38), - MMC_FIXUP("SEM32G", CID_MANFID_SANDISK, 0x100, add_quirk, - MMC_QUIRK_INAND_CMD38), - - /* - * Some MMC cards experience performance degradation with CMD23 - * instead of CMD12-bounded multiblock transfers. For now we'll - * black list what's bad... - * - Certain Toshiba cards. - * - * N.B. This doesn't affect SD cards. - */ - MMC_FIXUP("MMC08G", CID_MANFID_TOSHIBA, CID_OEMID_ANY, add_quirk_mmc, - MMC_QUIRK_BLK_NO_CMD23), - MMC_FIXUP("MMC16G", CID_MANFID_TOSHIBA, CID_OEMID_ANY, add_quirk_mmc, - MMC_QUIRK_BLK_NO_CMD23), - MMC_FIXUP("MMC32G", CID_MANFID_TOSHIBA, CID_OEMID_ANY, add_quirk_mmc, - MMC_QUIRK_BLK_NO_CMD23), - - /* - * Some Micron MMC cards needs longer data read timeout than - * indicated in CSD. - */ - MMC_FIXUP(CID_NAME_ANY, CID_MANFID_MICRON, 0x200, add_quirk_mmc, - MMC_QUIRK_LONG_READ_TIME), - - /* - * On these Samsung MoviNAND parts, performing secure erase or - * secure trim can result in unrecoverable corruption due to a - * firmware bug. - */ - MMC_FIXUP("M8G2FA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, - MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), - MMC_FIXUP("MAG4FA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, - MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), - MMC_FIXUP("MBG8FA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, - MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), - MMC_FIXUP("MCGAFA", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, - MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), - MMC_FIXUP("VAL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, - MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), - MMC_FIXUP("VYL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, - MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), - MMC_FIXUP("KYL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, - MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), - MMC_FIXUP("VZL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc, - MMC_QUIRK_SEC_ERASE_TRIM_BROKEN), - - END_FIXUP -}; - -static int mmc_blk_probe(struct mmc_card *card) -{ - struct mmc_blk_data *md, *part_md; - char cap_str[10]; - - /* - * Check that the card supports the command class(es) we need. - */ - if (!(card->csd.cmdclass & CCC_BLOCK_READ)) - return -ENODEV; - - mmc_fixup_device(card, blk_fixups); - - md = mmc_blk_alloc(card); - if (IS_ERR(md)) - return PTR_ERR(md); - - string_get_size((u64)get_capacity(md->disk), 512, STRING_UNITS_2, - cap_str, sizeof(cap_str)); - pr_info("%s: %s %s %s %s\n", - md->disk->disk_name, mmc_card_id(card), mmc_card_name(card), - cap_str, md->read_only ? "(ro)" : ""); - - if (mmc_blk_alloc_parts(card, md)) - goto out; - - dev_set_drvdata(&card->dev, md); - - if (mmc_add_disk(md)) - goto out; - - list_for_each_entry(part_md, &md->part, part) { - if (mmc_add_disk(part_md)) - goto out; - } - - pm_runtime_set_autosuspend_delay(&card->dev, 3000); - pm_runtime_use_autosuspend(&card->dev); - - /* - * Don't enable runtime PM for SD-combo cards here. Leave that - * decision to be taken during the SDIO init sequence instead. - */ - if (card->type != MMC_TYPE_SD_COMBO) { - pm_runtime_set_active(&card->dev); - pm_runtime_enable(&card->dev); - } - - return 0; - - out: - mmc_blk_remove_parts(card, md); - mmc_blk_remove_req(md); - return 0; -} - -static void mmc_blk_remove(struct mmc_card *card) -{ - struct mmc_blk_data *md = dev_get_drvdata(&card->dev); - - mmc_blk_remove_parts(card, md); - pm_runtime_get_sync(&card->dev); - mmc_claim_host(card->host); - mmc_blk_part_switch(card, md); - mmc_release_host(card->host); - if (card->type != MMC_TYPE_SD_COMBO) - pm_runtime_disable(&card->dev); - pm_runtime_put_noidle(&card->dev); - mmc_blk_remove_req(md); - dev_set_drvdata(&card->dev, NULL); -} - -static int _mmc_blk_suspend(struct mmc_card *card) -{ - struct mmc_blk_data *part_md; - struct mmc_blk_data *md = dev_get_drvdata(&card->dev); - - if (md) { - mmc_queue_suspend(&md->queue); - list_for_each_entry(part_md, &md->part, part) { - mmc_queue_suspend(&part_md->queue); - } - } - return 0; -} - -static void mmc_blk_shutdown(struct mmc_card *card) -{ - _mmc_blk_suspend(card); -} - -#ifdef CONFIG_PM_SLEEP -static int mmc_blk_suspend(struct device *dev) -{ - struct mmc_card *card = mmc_dev_to_card(dev); - - return _mmc_blk_suspend(card); -} - -static int mmc_blk_resume(struct device *dev) -{ - struct mmc_blk_data *part_md; - struct mmc_blk_data *md = dev_get_drvdata(dev); - - if (md) { - /* - * Resume involves the card going into idle state, - * so current partition is always the main one. - */ - md->part_curr = md->part_type; - mmc_queue_resume(&md->queue); - list_for_each_entry(part_md, &md->part, part) { - mmc_queue_resume(&part_md->queue); - } - } - return 0; -} -#endif - -static SIMPLE_DEV_PM_OPS(mmc_blk_pm_ops, mmc_blk_suspend, mmc_blk_resume); - -static struct mmc_driver mmc_driver = { - .drv = { - .name = "mmcblk", - .pm = &mmc_blk_pm_ops, - }, - .probe = mmc_blk_probe, - .remove = mmc_blk_remove, - .shutdown = mmc_blk_shutdown, -}; - -static int __init mmc_blk_init(void) -{ - int res; - - if (perdev_minors != CONFIG_MMC_BLOCK_MINORS) - pr_info("mmcblk: using %d minors per device\n", perdev_minors); - - max_devices = min(MAX_DEVICES, (1 << MINORBITS) / perdev_minors); - - res = register_blkdev(MMC_BLOCK_MAJOR, "mmc"); - if (res) - goto out; - - res = mmc_register_driver(&mmc_driver); - if (res) - goto out2; - - return 0; - out2: - unregister_blkdev(MMC_BLOCK_MAJOR, "mmc"); - out: - return res; -} - -static void __exit mmc_blk_exit(void) -{ - mmc_unregister_driver(&mmc_driver); - unregister_blkdev(MMC_BLOCK_MAJOR, "mmc"); -} - -module_init(mmc_blk_init); -module_exit(mmc_blk_exit); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Multimedia Card (MMC) block device driver"); - diff --git a/drivers/net/ethernet/nuvoton/npcm750_emc.c b/drivers/net/ethernet/nuvoton/npcm750_emc.c index c98eaa18d5a19f..745f665c2e79bf 100755 --- a/drivers/net/ethernet/nuvoton/npcm750_emc.c +++ b/drivers/net/ethernet/nuvoton/npcm750_emc.c @@ -40,7 +40,7 @@ #endif #define DRV_MODULE_NAME "npcm750-emc" -#define DRV_MODULE_VERSION "2.1" +#define DRV_MODULE_VERSION "2.3" /*---------------------------------------------------------------------------------------------------------*/ @@ -199,8 +199,17 @@ #define CAM0 0x0 #define RX_POLL_SIZE 16 -#define MAX_VLAN_SIZE 1518 -#define MAX_VLAN_SIZE_W_CRC (MAX_VLAN_SIZE + 4) // 1522 +#ifdef CONFIG_VLAN_8021Q +#define VLAN_SUPPORT +#endif + +#ifdef VLAN_SUPPORT +#define MAX_PACKET_SIZE 1518 +#define MAX_PACKET_SIZE_W_CRC (MAX_PACKET_SIZE + 4) // 1522 +#else +#define MAX_PACKET_SIZE 1514 +#define MAX_PACKET_SIZE_W_CRC (MAX_PACKET_SIZE + 4) // 1518 +#endif #define MII_TIMEOUT 100 @@ -277,7 +286,6 @@ struct npcm750_ether { int speed; int duplex; int need_reset; - char proc_filename[32]; char* dump_buf; #ifdef CONFIG_NPCM750_EMC_ETH_DEBUG @@ -294,6 +302,7 @@ struct npcm750_ether { #endif }; +static void npcm750_ether_set_multicast_list(struct net_device *dev); static int npcm750_info_dump(char* buf, int count, struct net_device *dev); #ifdef CONFIG_NPCM750_EMC_ETH_DEBUG void npcm750_clk_GetTimeStamp (u32 time_quad[2]); @@ -411,7 +420,7 @@ static void npcm750_write_cam(struct net_device *dev, static struct sk_buff * get_new_skb(struct net_device *dev, u32 i) { struct npcm750_ether *ether = netdev_priv(dev); - struct sk_buff *skb = dev_alloc_skb(roundup(MAX_VLAN_SIZE_W_CRC, 4)); + struct sk_buff *skb = dev_alloc_skb(roundup(MAX_PACKET_SIZE_W_CRC, 4)); if (skb == NULL) return NULL; @@ -424,7 +433,7 @@ static struct sk_buff * get_new_skb(struct net_device *dev, u32 i) { skb->dev = dev; (ether->rdesc + i)->buffer = dma_map_single(&dev->dev, skb->data, - roundup(MAX_VLAN_SIZE_W_CRC, 4), DMA_FROM_DEVICE); + roundup(MAX_PACKET_SIZE_W_CRC, 4), DMA_FROM_DEVICE); ether->rx_skb[i] = skb; return skb; @@ -501,7 +510,7 @@ static int npcm750_init_desc(struct net_device *dev) for(; i != 0; i--) { dma_unmap_single(&dev->dev, (dma_addr_t)((ether->rdesc + i)->buffer), - roundup(MAX_VLAN_SIZE_W_CRC, 4), DMA_FROM_DEVICE); + roundup(MAX_PACKET_SIZE_W_CRC, 4), DMA_FROM_DEVICE); dev_kfree_skb_any(ether->rx_skb[i]); ether->rx_skb[i] = NULL; } @@ -544,7 +553,7 @@ static void npcm750_free_desc(struct net_device *dev, bool free_also_descriptors for (i = 0; i < RX_DESC_SIZE; i++) { skb = ether->rx_skb[i]; if(skb != NULL) { - dma_unmap_single(&dev->dev, (dma_addr_t)((ether->rdesc + i)->buffer), roundup(MAX_VLAN_SIZE_W_CRC, 4), DMA_FROM_DEVICE); + dma_unmap_single(&dev->dev, (dma_addr_t)((ether->rdesc + i)->buffer), roundup(MAX_PACKET_SIZE_W_CRC, 4), DMA_FROM_DEVICE); dev_kfree_skb_any(skb); ether->rx_skb[i] = NULL; } @@ -577,10 +586,10 @@ static void npcm750_return_default_idle(struct net_device *dev) { struct npcm750_ether *ether = netdev_priv(dev); unsigned int val; - unsigned int saved_bits; + unsigned int mcmdr_bits; val = __raw_readl(REG_MCMDR); - saved_bits = val & (MCMDR_FDUP | MCMDR_OPMOD); + mcmdr_bits = val & (MCMDR_FDUP | MCMDR_OPMOD); //EMC_DEBUG("REG_MCMDR = 0x%08X\n", val); val |= SWR; __raw_writel(val, REG_MCMDR); @@ -590,7 +599,8 @@ static void npcm750_return_default_idle(struct net_device *dev) } while (val & SWR); //EMC_DEBUG("REG_MCMDR = 0x%08X\n", val); - __raw_writel(saved_bits, REG_MCMDR); + // restore values + __raw_writel(mcmdr_bits, REG_MCMDR); } @@ -603,7 +613,9 @@ static void npcm750_enable_mac_interrupt(struct net_device *dev) val = ENRXINTR | // Start of RX interrupts ENCRCE | EMRXOV | - // ENPTLE | // Since we support VLAN we don't want interrupt on long packets +#ifndef VLAN_SUPPORT + ENPTLE | // Since we don't support VLAN we want interrupt on long packets +#endif ENRXGD | ENALIE | ENRP | @@ -642,11 +654,14 @@ static void npcm750_set_global_maccmd(struct net_device *dev) val = __raw_readl(REG_MCMDR); //EMC_DEBUG("REG_MCMDR = 0x%08X\n", val); + val |= MCMDR_SPCRC | MCMDR_ENMDC | MCMDR_ACP | MCMDR_NDEF; +#ifdef VLAN_SUPPORT // we set ALP accept long packets since VLAN packets are 4 bytes longer than 1518 - val |= MCMDR_SPCRC | MCMDR_ENMDC | MCMDR_ACP | MCMDR_NDEF | MCMDR_ALP; - __raw_writel(val, REG_MCMDR); + val |= MCMDR_ALP; // limit receive length to 1522 bytes due to VLAN - __raw_writel(MAX_VLAN_SIZE_W_CRC, REG_DMARFC); + __raw_writel(MAX_PACKET_SIZE_W_CRC, REG_DMARFC); +#endif + __raw_writel(val, REG_MCMDR); } static void npcm750_enable_cam(struct net_device *dev) @@ -661,15 +676,6 @@ static void npcm750_enable_cam(struct net_device *dev) __raw_writel(val, REG_CAMEN); } -static void npcm750_enable_cam_command(struct net_device *dev) -{ - struct npcm750_ether *ether = netdev_priv(dev); - unsigned int val; - - val = CAMCMR_ECMP | CAMCMR_ABP | CAMCMR_AMP; - __raw_writel(val, REG_CAMCMR); -} - static void npcm750_set_curdest(struct net_device *dev) { @@ -704,7 +710,7 @@ static void npcm750_reset_mac(struct net_device *dev, int need_free) npcm750_set_curdest(dev); npcm750_enable_cam(dev); - npcm750_enable_cam_command(dev); + npcm750_ether_set_multicast_list(dev); npcm750_enable_mac_interrupt(dev); npcm750_set_global_maccmd(dev); ETH_ENABLE_TX; @@ -795,18 +801,23 @@ static int npcm750_ether_close(struct net_device *dev) { struct npcm750_ether *ether = netdev_priv(dev); - netif_stop_queue(dev); - napi_disable(ðer->napi); - free_irq(ether->txirq, dev); - free_irq(ether->rxirq, dev); - - npcm750_free_desc(dev, true); - if (ether->phy_dev) { phy_stop(ether->phy_dev); } + npcm750_return_default_idle(dev); + + msleep(10); + + free_irq(ether->txirq, dev); + free_irq(ether->rxirq, dev); + + netif_stop_queue(dev); + napi_disable(ðer->napi); + + npcm750_free_desc(dev, true); + if (ether->dump_buf) { kfree(ether->dump_buf); @@ -834,7 +845,7 @@ static int npcm750_clean_tx(struct net_device *dev) unsigned int cur_entry, entry, sl; if (ether->pending_tx == 0) { - return(0); + return 0; } cur_entry = __raw_readl(REG_CTXDSA); @@ -845,6 +856,8 @@ static int npcm750_clean_tx(struct net_device *dev) while (entry != cur_entry) { txbd = (ether->tdesc + ether->finish_tx); s = ether->tx_skb[ether->finish_tx]; + if (s == NULL) + break; #ifdef CONFIG_NPCM750_EMC_ETH_DEBUG ether->count_finish++; #endif @@ -910,11 +923,11 @@ static int npcm750_ether_start_xmit(struct sk_buff *skb, struct net_device *dev) skb->len, DMA_TO_DEVICE); ether->tx_skb[ether->cur_tx] = skb; - if (skb->len > MAX_VLAN_SIZE) + if (skb->len > MAX_PACKET_SIZE) { - dev_err(ðer->pdev->dev, "skb->len (= %d) > MAX_VLAN_SIZE (= %d)\n", skb->len, MAX_VLAN_SIZE); + dev_err(ðer->pdev->dev, "skb->len (= %d) > MAX_PACKET_SIZE (= %d)\n", skb->len, MAX_PACKET_SIZE); } - txbd->sl = skb->len > MAX_VLAN_SIZE ? MAX_VLAN_SIZE : skb->len; + txbd->sl = skb->len > MAX_PACKET_SIZE ? MAX_PACKET_SIZE : skb->len; wmb(); txbd->mode = TX_OWEN_DMA | PADDINGMODE | CRCMODE; @@ -1075,7 +1088,7 @@ static int npcm750_poll(struct napi_struct *napi, int budget) if (likely(status & RXDS_RXGD)) { - skb = dev_alloc_skb(roundup(MAX_VLAN_SIZE_W_CRC, 4)); + skb = dev_alloc_skb(roundup(MAX_PACKET_SIZE_W_CRC, 4)); if (!skb) { struct platform_device *pdev = ether->pdev; @@ -1083,7 +1096,7 @@ static int npcm750_poll(struct napi_struct *napi, int budget) ether->stats.rx_dropped++; goto rx_out; } - dma_unmap_single(&dev->dev, (dma_addr_t)rxbd->buffer, roundup(MAX_VLAN_SIZE_W_CRC, 4), DMA_FROM_DEVICE); + dma_unmap_single(&dev->dev, (dma_addr_t)rxbd->buffer, roundup(MAX_PACKET_SIZE_W_CRC, 4), DMA_FROM_DEVICE); skb_put(s, length); s->protocol = eth_type_trans(s, dev); @@ -1099,7 +1112,7 @@ static int npcm750_poll(struct napi_struct *napi, int budget) skb->dev = dev; rxbd->buffer = dma_map_single(&dev->dev, skb->data, - roundup(MAX_VLAN_SIZE_W_CRC, 4), DMA_FROM_DEVICE); + roundup(MAX_PACKET_SIZE_W_CRC, 4), DMA_FROM_DEVICE); ether->rx_skb[ether->cur_rx] = skb; rx_cnt++; #ifdef CONFIG_NPCM750_EMC_ETH_DEBUG @@ -1116,7 +1129,12 @@ static int npcm750_poll(struct napi_struct *napi, int budget) #endif } - if (unlikely(status & (RXDS_CRCE|RXDS_PTLE|RXDS_ALIE|RXDS_RP))) { +#ifdef VLAN_SUPPORT + if (unlikely(status & (RXDS_CRCE|RXDS_ALIE|RXDS_RP))) +#else + if (unlikely(status & (RXDS_CRCE|RXDS_ALIE|RXDS_RP|RXDS_PTLE))) +#endif + { ether->stats.rx_errors++; EMC_DEBUG("rx_errors = %lu status = 0x%08X\n", ether->stats.rx_errors, status); @@ -1129,10 +1147,13 @@ static int npcm750_poll(struct napi_struct *napi, int budget) } else if (status & RXDS_ALIE) { ether->stats.rx_frame_errors++; EMC_DEBUG("rx_frame_errors = %lu\n", ether->stats.rx_frame_errors); - } else if (status & RXDS_PTLE) { - ether->stats.rx_over_errors++; - EMC_DEBUG("rx_over_errors = %lu\n", ether->stats.rx_over_errors); } +#ifndef VLAN_SUPPORT + else if (status & RXDS_PTLE) { + ether->stats.rx_length_errors++; + EMC_DEBUG("rx_length_errors = %lu\n", ether->stats.rx_length_errors); + } +#endif } wmb(); @@ -1239,7 +1260,9 @@ static irqreturn_t npcm750_rx_interrupt(int irq, void *dev_id) // MISTA_RXINTR | // Receive - all RX interrupt set this MISTA_CRCE | // CRC Error // MISTA_RXOV | // Receive FIFO Overflow - we alread handled it - // MISTA_PTLE | // Packet Too Long is ignored since VLAN is supported +#ifndef VLAN_SUPPORT + MISTA_PTLE | // Packet Too Long is needed since VLAN is not supported +#endif // MISTA_RXGD | // Receive Good - this is the common good case MISTA_ALIE | // Alignment Error MISTA_RP | // Runt Packet @@ -1515,14 +1538,6 @@ static int npcm750_mii_setup(struct net_device *dev) ether->mii_bus->priv = ether; ether->mii_bus->parent = ðer->pdev->dev; - ether->mii_bus->irq[0] = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); - if (!ether->mii_bus->irq) { - err = -ENOMEM; - dev_err(&pdev->dev, "kmalloc() failed\n"); - goto out1; - - } - for (i = 0; i < PHY_MAX_ADDR; i++) ether->mii_bus->irq[i] = PHY_POLL; //ether->mii_bus->irq[1] = ?? write me after the irq number is known @@ -1567,8 +1582,7 @@ static int npcm750_mii_setup(struct net_device *dev) out3: mdiobus_unregister(ether->mii_bus); out2: - kfree(ether->mii_bus->irq); -out1: + kfree(ether->mii_bus->irq); mdiobus_free(ether->mii_bus); out0: @@ -1599,7 +1613,7 @@ static int npcm750_info_dump(char* buf, int count, struct net_device *dev) spin_lock_irqsave(ðer->lock, flags); /* ------basic driver information ---- */ - PROC_PRINT("%s version: %s\n","NPCM750 EMC driver", DRV_MODULE_VERSION); + PROC_PRINT("NPCM750 EMC %s driver version: %s\n", dev->name, DRV_MODULE_VERSION); REG_PRINT(REG_CAMCMR); REG_PRINT(REG_CAMEN); @@ -1785,11 +1799,12 @@ static int npcm750_proc_read(struct seq_file *sf, void *v) npcm750_info_dump(ether->dump_buf, print_size, dev); } - /*if (seq_printf(sf,"%s", ether->dump_buf) == 0) - { - kfree(ether->dump_buf); - ether->dump_buf = NULL; - }*/ + seq_printf(sf,"%s", ether->dump_buf); + + if (sf->count < sf->size) { + kfree(ether->dump_buf); + ether->dump_buf = NULL; + } return 0; } @@ -1817,6 +1832,7 @@ static int npcm750_ether_probe(struct platform_device *pdev) struct npcm750_ether *ether; struct net_device *dev; int error; + char proc_filename[32]; #ifdef CONFIG_OF struct clk* emc_clk = NULL; @@ -1968,9 +1984,8 @@ static int npcm750_ether_probe(struct platform_device *pdev) error = -ENODEV; goto failed_free_rxirq; } - snprintf(ether->proc_filename, sizeof(ether->proc_filename), "%s.%d", PROC_FILENAME, pdev->id ); - proc_create_data(ether->proc_filename, 0, NULL, &npcm750_ether_proc_fops, dev); - //create_proc_read_entry(ether->proc_filename, 0, NULL, npcm750_proc_read, dev); + snprintf(proc_filename, sizeof(proc_filename), "%s.%d", PROC_FILENAME, pdev->id ); + proc_create_data(proc_filename, 0, NULL, &npcm750_ether_proc_fops, dev); return 0; @@ -1992,9 +2007,10 @@ static int npcm750_ether_remove(struct platform_device *pdev) { struct net_device *dev = platform_get_drvdata(pdev); struct npcm750_ether *ether = netdev_priv(dev); + char proc_filename[32]; - snprintf(ether->proc_filename, sizeof(ether->proc_filename), "%s.%d", PROC_FILENAME, pdev->id ); - remove_proc_entry(ether->proc_filename, NULL); + snprintf(proc_filename, sizeof(proc_filename), "%s.%d", PROC_FILENAME, pdev->id ); + remove_proc_entry(proc_filename, NULL); unregister_netdev(dev); diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c index 0edccff781d19c..40c76ce6cfe1fd 100755 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-generic.c @@ -70,7 +70,6 @@ static int dwmac_generic_probe(struct platform_device *pdev) } static const struct of_device_id dwmac_generic_match[] = { - { .compatible = "nuvoton,npcm750-gmac"}, { .compatible = "st,spear600-gmac"}, { .compatible = "snps,dwmac-3.50a"}, { .compatible = "snps,dwmac-3.610"}, @@ -79,6 +78,7 @@ static const struct of_device_id dwmac_generic_match[] = { { .compatible = "snps,dwmac-4.00"}, { .compatible = "snps,dwmac-4.10a"}, { .compatible = "snps,dwmac"}, + { .compatible = "nuvoton,npcm750-gmac"}, { } }; MODULE_DEVICE_TABLE(of, dwmac_generic_match); diff --git a/drivers/tty/serial/npcmX50_uart.c b/drivers/tty/serial/npcmX50_uart.c index 7e373624f3ff7c..db657ceab9238d 100755 --- a/drivers/tty/serial/npcmX50_uart.c +++ b/drivers/tty/serial/npcmX50_uart.c @@ -498,62 +498,38 @@ static int __init npcmX50_console_setup(struct console *co, char *options); static void npcmX50_console_write(struct console *co, const char *s, unsigned int count); static int npcmX50_console_init(void); -#ifdef REG_READ -#undef REG_READ -#endif -static inline UINT8 REG_READ(unsigned char __iomem *mem ) { - return ioread8(mem); -} - -#ifdef REG_WRITE -#undef REG_WRITE -#endif -static inline void REG_WRITE(unsigned char __iomem *mem, UINT8 val ) { - iowrite8(val, mem); -} +#define regwrite8(mem, val) iowrite8(val, mem) -#ifdef SET_REG_FIELD -#undef SET_REG_FIELD -#endif /*---------------------------------------------------------------------------------------------------------*/ /* Set field of a register / variable according to the field offset and size */ /*---------------------------------------------------------------------------------------------------------*/ -static inline void SET_REG_FIELD(unsigned char __iomem *mem, bit_field_t bit_field, UINT8 val) { +static inline void set_reg_field8(unsigned char __iomem *mem, bit_field_t bit_field, UINT8 val) { UINT8 tmp = ioread8(mem); tmp &= ~(((1 << bit_field.size) - 1) << bit_field.offset); // mask the field size tmp |= val << bit_field.offset; // or with the requested value iowrite8(tmp, mem); } -#ifdef SET_VAR_FIELD -#undef SET_VAR_FIELD -#endif // bit_field should be of bit_field_t type -#define SET_VAR_FIELD(var, bit_field, value) { \ +#define set_var_field(var, bit_field, value) { \ typeof(var) tmp = var; \ tmp &= ~(((1 << bit_field.size) - 1) << bit_field.offset); /* mask the field size */ \ tmp |= value << bit_field.offset; /* or with the requested value */ \ var = tmp; \ } -#ifdef READ_REG_FIELD -#undef READ_REG_FIELD -#endif /*---------------------------------------------------------------------------------------------------------*/ /* Get field of a register / variable according to the field offset and size */ /*---------------------------------------------------------------------------------------------------------*/ -static inline UINT8 READ_REG_FIELD(unsigned char __iomem *mem, bit_field_t bit_field) { +static inline UINT8 read_reg_field8(unsigned char __iomem *mem, bit_field_t bit_field) { UINT8 tmp = ioread8(mem); tmp = tmp >> bit_field.offset; // shift right the offset tmp &= (1 << bit_field.size) - 1; // mask the size return tmp; } -#ifdef READ_VAR_FIELD -#undef READ_VAR_FIELD -#endif // bit_field should be of bit_field_t type -#define READ_VAR_FIELD(var, bit_field) ({ \ +#define read_var_field(var, bit_field) ({ \ typeof(var) tmp = var; \ tmp = tmp >> bit_field.offset; /* shift right the offset */ \ tmp &= (1 << bit_field.size) - 1; /* mask the size */ \ @@ -812,8 +788,8 @@ static int npcmx50_uart_init(NPCMX50_UART_DEV_T devNum, NPCMX50_UART_MUX_T muxMo /*-----------------------------------------------------------------------------------------------------*/ /* Disable interrupts */ /*-----------------------------------------------------------------------------------------------------*/ - REG_WRITE(UART_LCR(devNum), 0); // prepare to Init UART - REG_WRITE(UART_IER(devNum), 0x0); // Disable all UART interrupt + regwrite8(UART_LCR(devNum), 0); // prepare to Init UART + regwrite8(UART_IER(devNum), 0x0); // Disable all UART interrupt /*-----------------------------------------------------------------------------------------------------*/ /* Set baudrate */ @@ -831,13 +807,13 @@ static int npcmx50_uart_init(NPCMX50_UART_DEV_T devNum, NPCMX50_UART_MUX_T muxMo /* Set the RX FIFO trigger level, reset RX, TX FIFO */ /*-----------------------------------------------------------------------------------------------------*/ FCR_Val = 0; - SET_VAR_FIELD(FCR_Val, FCR_RFITL, FCR_RFITL_4B); - SET_VAR_FIELD(FCR_Val, FCR_TFR, 1); - SET_VAR_FIELD(FCR_Val, FCR_RFR, 1); - SET_VAR_FIELD(FCR_Val, FCR_FME, 1); + set_var_field(FCR_Val, FCR_RFITL, FCR_RFITL_4B); + set_var_field(FCR_Val, FCR_TFR, 1); + set_var_field(FCR_Val, FCR_RFR, 1); + set_var_field(FCR_Val, FCR_FME, 1); - REG_WRITE(UART_FCR(devNum), FCR_Val); - REG_WRITE(UART_TOR(devNum), 0x0); + regwrite8(UART_FCR(devNum), FCR_Val); + regwrite8(UART_TOR(devNum), 0x0); if (ret > 0) return -1; @@ -874,13 +850,13 @@ static int npcmx50_uart_putc(NPCMX50_UART_DEV_T devNum, const u8 c ) /*-----------------------------------------------------------------------------------------------------*/ /* wait until Tx ready */ /*-----------------------------------------------------------------------------------------------------*/ - while (!READ_REG_FIELD(UART_LSR(devNum), LSR_THRE)); + while (!read_reg_field8(UART_LSR(devNum), LSR_THRE)); /*-----------------------------------------------------------------------------------------------------*/ /* Put the char */ /*-----------------------------------------------------------------------------------------------------*/ - REG_WRITE(UART_THR(devNum), (c & 0xFF)); + regwrite8(UART_THR(devNum), (c & 0xFF)); return 0; } @@ -919,7 +895,7 @@ static u8 npcmx50_uart_getc( NPCMX50_UART_DEV_T devNum ) /*-----------------------------------------------------------------------------------------------------*/ /* Reading the char */ /*-----------------------------------------------------------------------------------------------------*/ - Ch = REG_READ(UART_RBR(devNum)) & 0xFF; + Ch = ioread8(UART_RBR(devNum)) & 0xFF; return Ch; } @@ -950,7 +926,7 @@ static int npcmx50_uart_putc_NB(NPCMX50_UART_DEV_T devNum, const u8 c ) /*-----------------------------------------------------------------------------------------------------*/ /* Put the char */ /*-----------------------------------------------------------------------------------------------------*/ - REG_WRITE(UART_THR(devNum), (c & 0xFF)); + regwrite8(UART_THR(devNum), (c & 0xFF)); return 0; } @@ -986,7 +962,7 @@ static int npcmx50_uart_getc_NB( NPCMX50_UART_DEV_T devNum, u8* c ) /*-----------------------------------------------------------------------------------------------------*/ /* Reading the char */ /*-----------------------------------------------------------------------------------------------------*/ - *c = (REG_READ(UART_RBR(devNum)) & 0xFF); + *c = (ioread8(UART_RBR(devNum)) & 0xFF); return 0; } @@ -1006,7 +982,7 @@ static int npcmx50_uart_getc_NB( NPCMX50_UART_DEV_T devNum, u8* c ) static bool npcmx50_uart_test_rx( NPCMX50_UART_DEV_T devNum ) { - if (READ_REG_FIELD(UART_LSR(devNum), LSR_RFDR)) + if (read_reg_field8(UART_LSR(devNum), LSR_RFDR)) return TRUE; else return FALSE; @@ -1024,7 +1000,7 @@ static bool npcmx50_uart_test_rx( NPCMX50_UART_DEV_T devNum ) /*---------------------------------------------------------------------------------------------------------*/ static bool npcmx50_uart_test_tx( NPCMX50_UART_DEV_T devNum ) { - if (!READ_REG_FIELD(UART_LSR(devNum), LSR_THRE)) + if (!read_reg_field8(UART_LSR(devNum), LSR_THRE)) return TRUE; else return FALSE; @@ -1060,12 +1036,12 @@ int npcmx50_uart_reset_fifo(NPCMX50_UART_DEV_T devNum, bool txFifo, bool rxFifo) /*-----------------------------------------------------------------------------------------------------*/ if (txFifo) { - SET_REG_FIELD(UART_FCR(devNum), FCR_TFR, 1); + set_reg_field8(UART_FCR(devNum), FCR_TFR, 1); } if (rxFifo) { - SET_REG_FIELD(UART_FCR(devNum), FCR_RFR, 1); + set_reg_field8(UART_FCR(devNum), FCR_RFR, 1); } return 0; @@ -1103,11 +1079,11 @@ static int npcmx50_uart_set_tx_irq_state(NPCMX50_UART_DEV_T devNum, bool On) /*-----------------------------------------------------------------------------------------------------*/ if (On) { - SET_REG_FIELD(UART_IER(devNum), IER_THREIE, 1); + set_reg_field8(UART_IER(devNum), IER_THREIE, 1); } else { - SET_REG_FIELD(UART_IER(devNum), IER_THREIE, 0); + set_reg_field8(UART_IER(devNum), IER_THREIE, 0); } return 0; @@ -1144,13 +1120,13 @@ static int npcmx50_uart_set_rx_irq_state(NPCMX50_UART_DEV_T devNum, bool On) /*-----------------------------------------------------------------------------------------------------*/ if (On) { - SET_REG_FIELD(UART_IER(devNum), IER_RDAIE, 1); - SET_REG_FIELD(UART_TOR(devNum), TOR_TOIE, 1); + set_reg_field8(UART_IER(devNum), IER_RDAIE, 1); + set_reg_field8(UART_TOR(devNum), TOR_TOIE, 1); } else { - SET_REG_FIELD(UART_IER(devNum), IER_RDAIE, 0); - SET_REG_FIELD(UART_TOR(devNum), TOR_TOIE, 0); + set_reg_field8(UART_IER(devNum), IER_RDAIE, 0); + set_reg_field8(UART_TOR(devNum), TOR_TOIE, 0); } return 0; @@ -1183,12 +1159,12 @@ static int npcmx50_uart_set_rx_config(NPCMX50_UART_DEV_T devNum, u8 timeout, NPC /*-----------------------------------------------------------------------------------------------------*/ /* Setting Rx interrupt timeout */ /*-----------------------------------------------------------------------------------------------------*/ - SET_REG_FIELD(UART_TOR(devNum), TOR_TOIC, (timeout & 0x7F)); + set_reg_field8(UART_TOR(devNum), TOR_TOIC, (timeout & 0x7F)); /*-----------------------------------------------------------------------------------------------------*/ /* Setting Rx interrupt FIFO trigger level */ /*-----------------------------------------------------------------------------------------------------*/ - SET_REG_FIELD(UART_FCR(devNum), FCR_RFITL, (triggerLevel<<2)); + set_reg_field8(UART_FCR(devNum), FCR_RFITL, (triggerLevel<<2)); return 0; } @@ -1223,16 +1199,16 @@ static int npcmx50_uart_set_parity(NPCMX50_UART_DEV_T devNum, NPCMX50_UART_PARIT /*-------------------------------------------------------------------------------------------------*/ /* Parity enable, choosing type */ /*-------------------------------------------------------------------------------------------------*/ - SET_REG_FIELD(UART_LCR(devNum), LCR_PBE, 1); + set_reg_field8(UART_LCR(devNum), LCR_PBE, 1); if (parity == NPCMX50_UART_PARITY_EVEN) { - SET_REG_FIELD(UART_LCR(devNum), LCR_EPE, 1); + set_reg_field8(UART_LCR(devNum), LCR_EPE, 1); } else if (parity == NPCMX50_UART_PARITY_ODD) { - SET_REG_FIELD(UART_LCR(devNum), LCR_EPE, 0); + set_reg_field8(UART_LCR(devNum), LCR_EPE, 0); } else { @@ -1249,7 +1225,7 @@ static int npcmx50_uart_set_parity(NPCMX50_UART_DEV_T devNum, NPCMX50_UART_PARIT /*-----------------------------------------------------------------------------------------------------*/ else { - SET_REG_FIELD(UART_LCR(devNum), LCR_PBE, 0); + set_reg_field8(UART_LCR(devNum), LCR_PBE, 0); } return 0; @@ -1280,11 +1256,11 @@ static int npcmx50_uart_set_bits_per_char(NPCMX50_UART_DEV_T devNum, u32 bits) switch (bits) { - case 5: SET_REG_FIELD(UART_LCR(devNum), LCR_WLS, LCR_WLS_5bit); break; - case 6: SET_REG_FIELD(UART_LCR(devNum), LCR_WLS, LCR_WLS_6bit); break; - case 7: SET_REG_FIELD(UART_LCR(devNum), LCR_WLS, LCR_WLS_7bit); break; + case 5: set_reg_field8(UART_LCR(devNum), LCR_WLS, LCR_WLS_5bit); break; + case 6: set_reg_field8(UART_LCR(devNum), LCR_WLS, LCR_WLS_6bit); break; + case 7: set_reg_field8(UART_LCR(devNum), LCR_WLS, LCR_WLS_7bit); break; default: - case 8: SET_REG_FIELD(UART_LCR(devNum), LCR_WLS, LCR_WLS_8bit); break; + case 8: set_reg_field8(UART_LCR(devNum), LCR_WLS, LCR_WLS_8bit); break; } return 0; @@ -1349,10 +1325,10 @@ static int npcmx50_uart_set_baud_rate(NPCMX50_UART_DEV_T devNum, NPCMX50_UART_BA /*-----------------------------------------------------------------------------------------------------*/ /* Set baud rate to baudRate bps */ /*-----------------------------------------------------------------------------------------------------*/ - SET_REG_FIELD(UART_LCR(devNum), LCR_DLAB, 1); // prepare to access Divisor - REG_WRITE(UART_DLL(devNum), LSB(divisor)); - REG_WRITE(UART_DLM(devNum), MSB(divisor)); - SET_REG_FIELD(UART_LCR(devNum), LCR_DLAB, 0); // prepare to access RBR, THR, IER + set_reg_field8(UART_LCR(devNum), LCR_DLAB, 1); // prepare to access Divisor + regwrite8(UART_DLL(devNum), LSB(divisor)); + regwrite8(UART_DLM(devNum), MSB(divisor)); + set_reg_field8(UART_LCR(devNum), LCR_DLAB, 0); // prepare to access RBR, THR, IER return ret; @@ -1386,11 +1362,11 @@ static int npcmx50_uart_set_stop_bit(NPCMX50_UART_DEV_T devNum, NPCMX50_UART_STO if (stopbit == NPCMX50_UART_STOPBIT_1) { - SET_REG_FIELD(UART_LCR(devNum), LCR_NSB, 0); + set_reg_field8(UART_LCR(devNum), LCR_NSB, 0); } else if (stopbit == NPCMX50_UART_STOPBIT_DYNAMIC) { - SET_REG_FIELD(UART_LCR(devNum), LCR_NSB, 1); + set_reg_field8(UART_LCR(devNum), LCR_NSB, 1); } else { @@ -1427,11 +1403,11 @@ static int npcmx50_uart_set_break(NPCMX50_UART_DEV_T devNum, bool state) if (state) { - SET_REG_FIELD(UART_LCR(devNum), LCR_BCB, 1); + set_reg_field8(UART_LCR(devNum), LCR_BCB, 1); } else { - SET_REG_FIELD(UART_LCR(devNum), LCR_BCB, 0); + set_reg_field8(UART_LCR(devNum), LCR_BCB, 0); } return 0; @@ -1457,12 +1433,12 @@ static int npcmx50_uart_isr(NPCMX50_UART_DEV_T devNum, UART_irq_callback_t rxCa UART_irq_callback_t txCallback, void* txParam) { int ret = 0; - u32 iir = REG_READ(UART_IIR(devNum)) & 0xF; + u32 iir = ioread8(UART_IIR(devNum)) & 0xF; /*-----------------------------------------------------------------------------------------------------*/ /* Checking if we got any interrupts at all */ /*-----------------------------------------------------------------------------------------------------*/ - if (READ_VAR_FIELD(iir, IIR_NIP)) + if (read_var_field(iir, IIR_NIP)) { /*-------------------------------------------------------------------------------------------------*/ /* if no interrupts actually occurred, we return "not handled" */ @@ -1471,7 +1447,7 @@ static int npcmx50_uart_isr(NPCMX50_UART_DEV_T devNum, UART_irq_callback_t rxCa } else { - switch (READ_VAR_FIELD(iir, IIR_IID)) + switch (read_var_field(iir, IIR_IID)) { /*---------------------------------------------------------------------------------------------*/ /* We don't support modem interrups yet */ @@ -1501,14 +1477,14 @@ static int npcmx50_uart_isr(NPCMX50_UART_DEV_T devNum, UART_irq_callback_t rxCa /*---------------------------------------------------------------------------------------------*/ case IIR_IID_RLS: { - u32 lsr = REG_READ(UART_LSR(devNum)); - if (READ_VAR_FIELD(lsr, LSR_OEI)) + u32 lsr = ioread8(UART_LSR(devNum)); + if (read_var_field(lsr, LSR_OEI)) ret = -EOVERFLOW; - else if (READ_VAR_FIELD(lsr, LSR_PEI)) + else if (read_var_field(lsr, LSR_PEI)) ret = -EILSEQ ; // HAL_ERROR_BAD_PARITY; - else if (READ_VAR_FIELD(lsr, LSR_FEI)) + else if (read_var_field(lsr, LSR_FEI)) ret = -EMSGSIZE ; // HAL_ERROR_BAD_FRAME; - else if (READ_VAR_FIELD(lsr, LSR_BII)) + else if (read_var_field(lsr, LSR_BII)) ret = -EIO; // break else ret = -1; @@ -2268,7 +2244,7 @@ static struct uart_ops npcmX50_serial_ops = static struct uart_driver npcmX50_uart_drv = { .owner = THIS_MODULE, - .dev_name = NPCMX50_SERIAL_NAME, + .dev_name = "npcmX50_serial", .nr = NPCMX50_UART_NUM_OF_MODULES, .cons = NPCMX50_SERIAL_CONSOLE, .driver_name = NPCMX50_SERIAL_NAME,