lkml.org 
[lkml]   [2008]   [Jan]   [25]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH] [MEMSTICK] Updates for the memstick driver
    * Mark shared inline functions as static

    * Use member-at-a-time assignment for protocol structures

    * Comments for publicly exported functions

    * Use end_queued_request to end unhandled block layer requests

    * Use sysfs attribute group to export MSPro attributes

    * Fix includes

    * Use scnprintf instead of snprintf where string length matters

    * Remove spurious get_device/put_device in probe method


    diff --git a/drivers/memstick/core/memstick.c b/drivers/memstick/core/memstick.c
    index 46e5f9b..bba467f 100644
    --- a/drivers/memstick/core/memstick.c
    +++ b/drivers/memstick/core/memstick.c
    @@ -12,11 +12,10 @@
    *
    */

    -#include <linux/tifm.h>
    #include <linux/memstick.h>
    #include <linux/idr.h>
    -#include <linux/scatterlist.h>
    #include <linux/fs.h>
    +#include <linux/delay.h>

    #define DRIVER_NAME "memstick"
    #define DRIVER_VERSION "0.2"
    @@ -86,13 +85,11 @@ static int memstick_device_probe(struct device *dev)
    driver);
    int rc = -ENODEV;

    - get_device(dev);
    if (dev->driver && drv->probe) {
    rc = drv->probe(card);
    if (!rc)
    - return 0;
    + get_device(dev);
    }
    - put_device(dev);
    return rc;
    }

    @@ -205,12 +202,26 @@ static int memstick_dummy_check(struct memstick_dev *card)
    return 0;
    }

    +/**
    + * memstick_detect_change - schedule media detection on memstick host
    + * @host - host to use
    + */
    void memstick_detect_change(struct memstick_host *host)
    {
    queue_work(workqueue, &host->media_checker);
    }
    EXPORT_SYMBOL(memstick_detect_change);

    +/**
    + * memstick_next_req - called by host driver to obtain next request to process
    + * @host - host to use
    + * @mrq - pointer to stick the request to
    + *
    + * Host calls this function from idle state (*mrq == NULL) or after finishing
    + * previous request (*mrq should point to it). If previous request was
    + * unsuccessful, it is retried for predetermined number of times. Return value
    + * of 0 means that new request was assigned to the host.
    + */
    int memstick_next_req(struct memstick_host *host, struct memstick_request **mrq)
    {
    int rc = -ENXIO;
    @@ -233,6 +244,10 @@ int memstick_next_req(struct memstick_host *host, struct memstick_request
    **mrq)
    }
    EXPORT_SYMBOL(memstick_next_req);

    +/**
    + * memstick_new_req - notify the host that some requests are pending
    + * @host - host to use
    + */
    void memstick_new_req(struct memstick_host *host)
    {
    host->retries = cmd_retries;
    @@ -240,6 +255,12 @@ void memstick_new_req(struct memstick_host *host)
    }
    EXPORT_SYMBOL(memstick_new_req);

    +/**
    + * memstick_init_req_sg - set request fields needed for bulk data transfer
    + * @mrq - request to use
    + * @tpc - memstick Transport Protocol Command
    + * @sg - TPC argument
    + */
    void memstick_init_req_sg(struct memstick_request *mrq, unsigned char tpc,
    struct scatterlist *sg)
    {
    @@ -261,6 +282,17 @@ void memstick_init_req_sg(struct memstick_request *mrq, unsigned char tpc,
    }
    EXPORT_SYMBOL(memstick_init_req_sg);

    +/**
    + * memstick_init_req - set request fields needed for short data transfer
    + * @mrq - request to use
    + * @tpc - memstick Transport Protocol Command
    + * @buf - TPC argument buffer
    + * @length - TPC argument size
    + *
    + * The intended use of this function (transfer of data items several bytes
    + * in size) allows us to just copy the value between request structure and
    + * user supplied buffer.
    + */
    void memstick_init_req(struct memstick_request *mrq, unsigned char tpc,
    void *buf, size_t length)
    {
    @@ -285,6 +317,13 @@ void memstick_init_req(struct memstick_request *mrq, unsigned char tpc,
    }
    EXPORT_SYMBOL(memstick_init_req);

    +/*
    + * Functions prefixed with "h_" are protocol callbacks. They can be called from
    + * interrupt context. Return value of 0 means that request processing is still
    + * ongoing, while special error value of -EAGAIN means that current request is
    + * finished (and request processor should come back some time later).
    + */
    +
    static int h_memstick_read_dev_id(struct memstick_dev *card,
    struct memstick_request **mrq)
    {
    @@ -298,12 +337,10 @@ static int h_memstick_read_dev_id(struct memstick_dev *card,
    } else {
    if (!(*mrq)->error) {
    memcpy(&id_reg, (*mrq)->data, sizeof(id_reg));
    - card->id = (struct memstick_device_id){
    - .match_flags = MEMSTICK_MATCH_ALL,
    - .type = id_reg.type,
    - .category = id_reg.category,
    - .class = id_reg.class
    - };
    + card->id.match_flags = MEMSTICK_MATCH_ALL;
    + card->id.type = id_reg.type;
    + card->id.category = id_reg.category;
    + card->id.class = id_reg.class;
    }
    complete(&card->mrq_complete);
    return -EAGAIN;
    @@ -325,6 +362,11 @@ static int h_memstick_set_rw_addr(struct memstick_dev *card,
    }
    }

    +/**
    + * memstick_set_rw_addr - issue SET_RW_REG_ADDR request and wait for it to
    + * complete
    + * @card - media device to use
    + */
    int memstick_set_rw_addr(struct memstick_dev *card)
    {
    card->next_request = h_memstick_set_rw_addr;
    @@ -351,12 +393,10 @@ static struct memstick_dev *memstick_alloc_card(struct memstick_host *host)
    card->dev.release = memstick_free_card;
    card->check = memstick_dummy_check;

    - card->reg_addr = (struct ms_register_addr){
    - offsetof(struct ms_register, id),
    - sizeof(id_reg),
    - offsetof(struct ms_register, id),
    - sizeof(id_reg)
    - };
    + card->reg_addr.r_offset = offsetof(struct ms_register, id);
    + card->reg_addr.r_length = sizeof(id_reg);
    + card->reg_addr.w_offset = offsetof(struct ms_register, id);
    + card->reg_addr.w_length = sizeof(id_reg);

    init_completion(&card->mrq_complete);

    @@ -433,6 +473,11 @@ static void memstick_check(struct work_struct *work)
    dev_dbg(host->cdev.dev, "memstick_check finished\n");
    }

    +/**
    + * memstick_alloc_host - allocate a memstick_host structure
    + * @extra: size of the user private data to allocate
    + * @dev: parent device of the host
    + */
    struct memstick_host *memstick_alloc_host(unsigned int extra,
    struct device *dev)
    {
    @@ -450,6 +495,10 @@ struct memstick_host *memstick_alloc_host(unsigned int extra,
    }
    EXPORT_SYMBOL(memstick_alloc_host);

    +/**
    + * memstick_add_host - start request processing on memstick host
    + * @host - host to use
    + */
    int memstick_add_host(struct memstick_host *host)
    {
    int rc;
    @@ -480,6 +529,10 @@ int memstick_add_host(struct memstick_host *host)
    }
    EXPORT_SYMBOL(memstick_add_host);

    +/**
    + * memstick_remove_host - stop request processing on memstick host
    + * @host - host to use
    + */
    void memstick_remove_host(struct memstick_host *host)
    {
    flush_workqueue(workqueue);
    @@ -497,6 +550,10 @@ void memstick_remove_host(struct memstick_host *host)
    }
    EXPORT_SYMBOL(memstick_remove_host);

    +/**
    + * memstick_free_host - free memstick host
    + * @host - host to use
    + */
    void memstick_free_host(struct memstick_host *host)
    {
    mutex_destroy(&host->lock);
    diff --git a/drivers/memstick/core/mspro_block.c b/drivers/memstick/core/mspro_block.c
    index c029dee..f09b74f 100644
    --- a/drivers/memstick/core/mspro_block.c
    +++ b/drivers/memstick/core/mspro_block.c
    @@ -13,7 +13,6 @@
    */

    #include <linux/blkdev.h>
    -#include <linux/scatterlist.h>
    #include <linux/idr.h>
    #include <linux/hdreg.h>
    #include <linux/kthread.h>
    @@ -44,10 +43,10 @@ enum {

    struct mspro_sys_attr {
    size_t size;
    - unsigned char *data;
    + void *data;
    unsigned char id;
    char name[32];
    - struct device_attribute sys_attr;
    + struct device_attribute dev_attr;
    };

    struct mspro_attr_entry {
    @@ -144,8 +143,7 @@ struct mspro_block_data {
    int (*mrq_handler)(struct memstick_dev *card,
    struct memstick_request **mrq);

    - unsigned char attr_count;
    - struct mspro_sys_attr *attributes;
    + struct attribute_group attr_group;

    struct scatterlist req_sg[MSPRO_BLOCK_MAX_SEGS];
    unsigned int seg_count;
    @@ -229,6 +227,13 @@ static struct block_device_operations ms_block_bdops = {

    /*** Information ***/

    +static struct mspro_sys_attr *mspro_from_sysfs_attr(struct attribute *attr)
    +{
    + struct device_attribute *dev_attr
    + = container_of(attr, struct device_attribute, attr);
    + return container_of(dev_attr, struct mspro_sys_attr, dev_attr);
    +}
    +
    static const char *mspro_block_attr_name(unsigned char tag)
    {
    switch (tag) {
    @@ -261,20 +266,20 @@ static ssize_t mspro_block_attr_show_default(struct device *dev,
    struct device_attribute *attr,
    char *buffer)
    {
    - struct mspro_sys_attr *x_attr = container_of(attr,
    + struct mspro_sys_attr *s_attr = container_of(attr,
    struct mspro_sys_attr,
    - sys_attr);
    + dev_attr);

    ssize_t cnt, rc = 0;

    - for (cnt = 0; cnt < x_attr->size; cnt++) {
    + for (cnt = 0; cnt < s_attr->size; cnt++) {
    if (cnt && !(cnt % 16)) {
    if (PAGE_SIZE - rc)
    buffer[rc++] = '\n';
    }

    - rc += snprintf(buffer + rc, PAGE_SIZE - rc, "%02x ",
    - x_attr->data[cnt]);
    + rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "%02x ",
    + ((unsigned char *)s_attr->data)[cnt]);
    }
    return rc;
    }
    @@ -285,63 +290,66 @@ static ssize_t mspro_block_attr_show_sysinfo(struct device *dev,
    {
    struct mspro_sys_attr *x_attr = container_of(attr,
    struct mspro_sys_attr,
    - sys_attr);
    - struct mspro_sys_info *x_sys = (struct mspro_sys_info *)x_attr->data;
    + dev_attr);
    + struct mspro_sys_info *x_sys = x_attr->data;
    ssize_t rc = 0;

    - rc += snprintf(buffer + rc, PAGE_SIZE - rc, "class: %x\n",
    - x_sys->class);
    - rc += snprintf(buffer + rc, PAGE_SIZE - rc, "block size: %x\n",
    - be16_to_cpu(x_sys->block_size));
    - rc += snprintf(buffer + rc, PAGE_SIZE - rc, "block count: %x\n",
    - be16_to_cpu(x_sys->block_count));
    - rc += snprintf(buffer + rc, PAGE_SIZE - rc, "user block count: %x\n",
    - be16_to_cpu(x_sys->user_block_count));
    - rc += snprintf(buffer + rc, PAGE_SIZE - rc, "page size: %x\n",
    - be16_to_cpu(x_sys->page_size));
    - rc += snprintf(buffer + rc, PAGE_SIZE - rc, "assembly date: "
    - "%d %04u-%02u-%02u %02u:%02u:%02u\n",
    - x_sys->assembly_date[0],
    - be16_to_cpu(*(unsigned short *)&x_sys->assembly_date[1]),
    - x_sys->assembly_date[3], x_sys->assembly_date[4],
    - x_sys->assembly_date[5], x_sys->assembly_date[6],
    - x_sys->assembly_date[7]);
    - rc += snprintf(buffer + rc, PAGE_SIZE - rc, "serial number: %x\n",
    - be32_to_cpu(x_sys->serial_number));
    - rc += snprintf(buffer + rc, PAGE_SIZE - rc, "assembly maker code: %x\n",
    - x_sys->assembly_maker_code);
    - rc += snprintf(buffer + rc, PAGE_SIZE - rc, "assembly model code: "
    - "%02x%02x%02x\n", x_sys->assembly_model_code[0],
    - x_sys->assembly_model_code[1],
    - x_sys->assembly_model_code[2]);
    - rc += snprintf(buffer + rc, PAGE_SIZE - rc, "memory maker code: %x\n",
    - be16_to_cpu(x_sys->memory_maker_code));
    - rc += snprintf(buffer + rc, PAGE_SIZE - rc, "memory model code: %x\n",
    - be16_to_cpu(x_sys->memory_model_code));
    - rc += snprintf(buffer + rc, PAGE_SIZE - rc, "vcc: %x\n",
    - x_sys->vcc);
    - rc += snprintf(buffer + rc, PAGE_SIZE - rc, "vpp: %x\n",
    - x_sys->vpp);
    - rc += snprintf(buffer + rc, PAGE_SIZE - rc, "controller number: %x\n",
    - be16_to_cpu(x_sys->controller_number));
    - rc += snprintf(buffer + rc, PAGE_SIZE - rc, "controller function: %x\n",
    - be16_to_cpu(x_sys->controller_function));
    - rc += snprintf(buffer + rc, PAGE_SIZE - rc, "start sector: %x\n",
    - be16_to_cpu(x_sys->start_sector));
    - rc += snprintf(buffer + rc, PAGE_SIZE - rc, "unit size: %x\n",
    - be16_to_cpu(x_sys->unit_size));
    - rc += snprintf(buffer + rc, PAGE_SIZE - rc, "sub class: %x\n",
    - x_sys->ms_sub_class);
    - rc += snprintf(buffer + rc, PAGE_SIZE - rc, "interface type: %x\n",
    - x_sys->interface_type);
    - rc += snprintf(buffer + rc, PAGE_SIZE - rc, "controller code: %x\n",
    - be16_to_cpu(x_sys->controller_code));
    - rc += snprintf(buffer + rc, PAGE_SIZE - rc, "format type: %x\n",
    - x_sys->format_type);
    - rc += snprintf(buffer + rc, PAGE_SIZE - rc, "device type: %x\n",
    - x_sys->device_type);
    - rc += snprintf(buffer + rc, PAGE_SIZE - rc, "mspro id: %s\n",
    - x_sys->mspro_id);
    + rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "class: %x\n",
    + x_sys->class);
    + rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "block size: %x\n",
    + be16_to_cpu(x_sys->block_size));
    + rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "block count: %x\n",
    + be16_to_cpu(x_sys->block_count));
    + rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "user block count: %x\n",
    + be16_to_cpu(x_sys->user_block_count));
    + rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "page size: %x\n",
    + be16_to_cpu(x_sys->page_size));
    + rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "assembly date: "
    + "%d %04u-%02u-%02u %02u:%02u:%02u\n",
    + x_sys->assembly_date[0],
    + be16_to_cpu(*(unsigned short *)
    + &x_sys->assembly_date[1]),
    + x_sys->assembly_date[3], x_sys->assembly_date[4],
    + x_sys->assembly_date[5], x_sys->assembly_date[6],
    + x_sys->assembly_date[7]);
    + rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "serial number: %x\n",
    + be32_to_cpu(x_sys->serial_number));
    + rc += scnprintf(buffer + rc, PAGE_SIZE - rc,
    + "assembly maker code: %x\n",
    + x_sys->assembly_maker_code);
    + rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "assembly model code: "
    + "%02x%02x%02x\n", x_sys->assembly_model_code[0],
    + x_sys->assembly_model_code[1],
    + x_sys->assembly_model_code[2]);
    + rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "memory maker code: %x\n",
    + be16_to_cpu(x_sys->memory_maker_code));
    + rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "memory model code: %x\n",
    + be16_to_cpu(x_sys->memory_model_code));
    + rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "vcc: %x\n",
    + x_sys->vcc);
    + rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "vpp: %x\n",
    + x_sys->vpp);
    + rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "controller number: %x\n",
    + be16_to_cpu(x_sys->controller_number));
    + rc += scnprintf(buffer + rc, PAGE_SIZE - rc,
    + "controller function: %x\n",
    + be16_to_cpu(x_sys->controller_function));
    + rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "start sector: %x\n",
    + be16_to_cpu(x_sys->start_sector));
    + rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "unit size: %x\n",
    + be16_to_cpu(x_sys->unit_size));
    + rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "sub class: %x\n",
    + x_sys->ms_sub_class);
    + rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "interface type: %x\n",
    + x_sys->interface_type);
    + rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "controller code: %x\n",
    + be16_to_cpu(x_sys->controller_code));
    + rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "format type: %x\n",
    + x_sys->format_type);
    + rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "device type: %x\n",
    + x_sys->device_type);
    + rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "mspro id: %s\n",
    + x_sys->mspro_id);
    return rc;
    }

    @@ -349,11 +357,11 @@ static ssize_t mspro_block_attr_show_modelname(struct device *dev,
    struct device_attribute *attr,
    char *buffer)
    {
    - struct mspro_sys_attr *x_attr = container_of(attr,
    + struct mspro_sys_attr *s_attr = container_of(attr,
    struct mspro_sys_attr,
    - sys_attr);
    + dev_attr);

    - return snprintf(buffer, PAGE_SIZE, "%s", x_attr->data);
    + return scnprintf(buffer, PAGE_SIZE, "%s", (char *)s_attr->data);
    }

    static ssize_t mspro_block_attr_show_mbr(struct device *dev,
    @@ -362,31 +370,31 @@ static ssize_t mspro_block_attr_show_mbr(struct device *dev,
    {
    struct mspro_sys_attr *x_attr = container_of(attr,
    struct mspro_sys_attr,
    - sys_attr);
    - struct mspro_mbr *x_mbr = (struct mspro_mbr *)x_attr->data;
    + dev_attr);
    + struct mspro_mbr *x_mbr = x_attr->data;
    ssize_t rc = 0;

    - rc += snprintf(buffer + rc, PAGE_SIZE - rc, "boot partition: %x\n",
    - x_mbr->boot_partition);
    - rc += snprintf(buffer + rc, PAGE_SIZE - rc, "start head: %x\n",
    - x_mbr->start_head);
    - rc += snprintf(buffer + rc, PAGE_SIZE - rc, "start sector: %x\n",
    - x_mbr->start_sector);
    - rc += snprintf(buffer + rc, PAGE_SIZE - rc, "start cylinder: %x\n",
    - x_mbr->start_cylinder);
    - rc += snprintf(buffer + rc, PAGE_SIZE - rc, "partition type: %x\n",
    - x_mbr->partition_type);
    - rc += snprintf(buffer + rc, PAGE_SIZE - rc, "end head: %x\n",
    - x_mbr->end_head);
    - rc += snprintf(buffer + rc, PAGE_SIZE - rc, "end sector: %x\n",
    - x_mbr->end_sector);
    - rc += snprintf(buffer + rc, PAGE_SIZE - rc, "end cylinder: %x\n",
    - x_mbr->end_cylinder);
    - rc += snprintf(buffer + rc, PAGE_SIZE - rc, "start sectors: %x\n",
    - x_mbr->start_sectors);
    - rc += snprintf(buffer + rc, PAGE_SIZE - rc,
    - "sectors per partition: %x\n",
    - x_mbr->sectors_per_partition);
    + rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "boot partition: %x\n",
    + x_mbr->boot_partition);
    + rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "start head: %x\n",
    + x_mbr->start_head);
    + rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "start sector: %x\n",
    + x_mbr->start_sector);
    + rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "start cylinder: %x\n",
    + x_mbr->start_cylinder);
    + rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "partition type: %x\n",
    + x_mbr->partition_type);
    + rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "end head: %x\n",
    + x_mbr->end_head);
    + rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "end sector: %x\n",
    + x_mbr->end_sector);
    + rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "end cylinder: %x\n",
    + x_mbr->end_cylinder);
    + rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "start sectors: %x\n",
    + x_mbr->start_sectors);
    + rc += scnprintf(buffer + rc, PAGE_SIZE - rc,
    + "sectors per partition: %x\n",
    + x_mbr->sectors_per_partition);
    return rc;
    }

    @@ -396,20 +404,20 @@ static ssize_t mspro_block_attr_show_devinfo(struct device *dev,
    {
    struct mspro_sys_attr *x_attr = container_of(attr,
    struct mspro_sys_attr,
    - sys_attr);
    - struct mspro_devinfo *x_devinfo = (struct mspro_devinfo *)x_attr->data;
    + dev_attr);
    + struct mspro_devinfo *x_devinfo = x_attr->data;
    ssize_t rc = 0;

    - rc += snprintf(buffer + rc, PAGE_SIZE - rc, "cylinders: %x\n",
    - be16_to_cpu(x_devinfo->cylinders));
    - rc += snprintf(buffer + rc, PAGE_SIZE - rc, "heads: %x\n",
    - be16_to_cpu(x_devinfo->heads));
    - rc += snprintf(buffer + rc, PAGE_SIZE - rc, "bytes per track: %x\n",
    - be16_to_cpu(x_devinfo->bytes_per_track));
    - rc += snprintf(buffer + rc, PAGE_SIZE - rc, "bytes per sector: %x\n",
    - be16_to_cpu(x_devinfo->bytes_per_sector));
    - rc += snprintf(buffer + rc, PAGE_SIZE - rc, "sectors per track: %x\n",
    - be16_to_cpu(x_devinfo->sectors_per_track));
    + rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "cylinders: %x\n",
    + be16_to_cpu(x_devinfo->cylinders));
    + rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "heads: %x\n",
    + be16_to_cpu(x_devinfo->heads));
    + rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "bytes per track: %x\n",
    + be16_to_cpu(x_devinfo->bytes_per_track));
    + rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "bytes per sector: %x\n",
    + be16_to_cpu(x_devinfo->bytes_per_sector));
    + rc += scnprintf(buffer + rc, PAGE_SIZE - rc, "sectors per track: %x\n",
    + be16_to_cpu(x_devinfo->sectors_per_track));
    return rc;
    }

    @@ -429,39 +437,15 @@ static sysfs_show_t mspro_block_attr_show(unsigned char tag)
    }
    }

    -static int mspro_block_sysfs_register(struct memstick_dev *card)
    -{
    - struct mspro_block_data *msb = memstick_get_drvdata(card);
    - int cnt, rc = 0;
    -
    - for (cnt = 0; cnt < msb->attr_count; cnt++) {
    - rc = device_create_file(&card->dev,
    - &msb->attributes[cnt].sys_attr);
    -
    - if (rc) {
    - if (cnt) {
    - for (cnt--; cnt >= 0; cnt--)
    - device_remove_file(&card->dev,
    - &msb->attributes[cnt]
    - .sys_attr);
    - }
    - break;
    - }
    - }
    - return rc;
    -}
    -
    -static void mspro_block_sysfs_unregister(struct memstick_dev *card)
    -{
    - struct mspro_block_data *msb = memstick_get_drvdata(card);
    - int cnt;
    -
    - for (cnt = 0; cnt < msb->attr_count; cnt++)
    - device_remove_file(&card->dev, &msb->attributes[cnt].sys_attr);
    -}
    -
    /*** Protocol handlers ***/

    +/*
    + * Functions prefixed with "h_" are protocol callbacks. They can be called from
    + * interrupt context. Return value of 0 means that request processing is still
    + * ongoing, while special error value of -EAGAIN means that current request is
    + * finished (and request processor should come back some time later).
    + */
    +
    static int h_mspro_block_req_init(struct memstick_dev *card,
    struct memstick_request **mrq)
    {
    @@ -642,12 +626,10 @@ static void mspro_block_process_request(struct memstick_dev *card,

    t_sec = req->sector;
    sector_div(t_sec, msb->page_size >> 9);
    - param = (struct mspro_param_register) {
    - .system = msb->system,
    - .data_count = cpu_to_be16(page_count),
    - .data_address = cpu_to_be32((uint32_t)t_sec),
    - .cmd_param = 0
    - };
    + param.system = msb->system;
    + param.data_count = cpu_to_be16(page_count);
    + param.data_address = cpu_to_be32((uint32_t)t_sec);
    + param.cmd_param = 0;

    msb->data_dir = rq_data_dir(req);
    msb->transfer_cmd = msb->data_dir == READ
    @@ -755,17 +737,12 @@ static void mspro_block_request(struct request_queue *q)
    struct mspro_block_data *msb = memstick_get_drvdata(card);
    struct request *req = NULL;

    - if (!msb->q_thread) {
    - for (req = elv_next_request(q); req;
    - req = elv_next_request(q)) {
    - while (end_that_request_chunk(req, -ENODEV,
    - req->current_nr_sectors
    - << 9)) {}
    - end_that_request_last(req, -ENODEV);
    - }
    - } else {
    + if (msb->q_thread) {
    msb->has_request = 1;
    wake_up_all(&msb->q_wait);
    + } else {
    + while ((req = elv_next_request(q)) != NULL)
    + end_queued_request(req, -ENODEV);
    }
    }

    @@ -821,6 +798,10 @@ static int mspro_block_switch_to_parallel(struct memstick_dev *card)
    return 0;
    }

    +/* Memory allocated for attributes by this function should be freed by
    + * mspro_block_data_clear, no matter if the initialization process succeded
    + * or failed.
    + */
    static int mspro_block_read_attributes(struct memstick_dev *card)
    {
    struct mspro_block_data *msb = memstick_get_drvdata(card);
    @@ -831,8 +812,9 @@ static int mspro_block_read_attributes(struct memstick_dev *card)
    .cmd_param = 0
    };
    struct mspro_attribute *attr = NULL;
    + struct mspro_sys_attr *s_attr = NULL;
    unsigned char *buffer = NULL;
    - int cnt, rc;
    + int cnt, rc, attr_count;
    unsigned int addr;
    unsigned short page_count;

    @@ -868,18 +850,18 @@ static int mspro_block_read_attributes(struct memstick_dev *card)
    if (attr->count > MSPRO_BLOCK_MAX_ATTRIBUTES) {
    printk(KERN_WARNING "%s: way too many attribute entries\n",
    card->dev.bus_id);
    - msb->attr_count = MSPRO_BLOCK_MAX_ATTRIBUTES;
    + attr_count = MSPRO_BLOCK_MAX_ATTRIBUTES;
    } else
    - msb->attr_count = attr->count;
    + attr_count = attr->count;

    - msb->attributes = kzalloc(msb->attr_count
    - * sizeof(struct mspro_sys_attr),
    - GFP_KERNEL);
    - if (!msb->attributes) {
    - msb->attr_count = 0;
    + msb->attr_group.attrs = kzalloc((attr_count + 1)
    + * sizeof(struct attribute),
    + GFP_KERNEL);
    + if (!msb->attr_group.attrs) {
    rc = -ENOMEM;
    goto out_free_attr;
    }
    + msb->attr_group.name = "media_attributes";

    buffer = kmalloc(msb->page_size, GFP_KERNEL);
    if (!buffer) {
    @@ -889,40 +871,37 @@ static int mspro_block_read_attributes(struct memstick_dev *card)
    memcpy(buffer, (char *)attr, msb->page_size);
    page_count = 1;

    - for (cnt = 0; cnt < msb->attr_count; cnt++) {
    + for (cnt = 0; cnt < attr_count; ++cnt) {
    + s_attr = kzalloc(sizeof(struct mspro_sys_attr), GFP_KERNEL);
    + if (!s_attr) {
    + rc = -ENOMEM;
    + goto out_free_buffer;
    + }
    +
    + msb->attr_group.attrs[cnt] = &s_attr->dev_attr.attr;
    addr = be32_to_cpu(attr->entries[cnt].address);
    rc = be32_to_cpu(attr->entries[cnt].size);
    dev_dbg(&card->dev, "adding attribute %d: id %x, address %x, "
    "size %x\n", cnt, attr->entries[cnt].id, addr, rc);
    - msb->attributes[cnt].id = attr->entries[cnt].id;
    - if (mspro_block_attr_name(attr->entries[cnt].id))
    - snprintf(msb->attributes[cnt].name,
    - sizeof(msb->attributes[cnt].name), "%s",
    + s_attr->id = attr->entries[cnt].id;
    + if (mspro_block_attr_name(s_attr->id))
    + snprintf(s_attr->name, sizeof(s_attr->name), "%s",
    mspro_block_attr_name(attr->entries[cnt].id));
    else
    - snprintf(msb->attributes[cnt].name,
    - sizeof(msb->attributes[cnt].name),
    - "attr_x%02x",
    - attr->entries[cnt].id);
    -
    - msb->attributes[cnt].sys_attr
    - = (struct device_attribute){
    - .attr = {
    - .name = msb->attributes[cnt].name,
    - .mode = S_IRUGO,
    - .owner = THIS_MODULE
    - },
    - .show = mspro_block_attr_show(
    - msb->attributes[cnt].id),
    - .store = NULL
    - };
    + snprintf(s_attr->name, sizeof(s_attr->name),
    + "attr_x%02x", attr->entries[cnt].id);
    +
    + s_attr->dev_attr.attr.name = s_attr->name;
    + s_attr->dev_attr.attr.mode = S_IRUGO;
    + s_attr->dev_attr.attr.owner = THIS_MODULE;
    + s_attr->dev_attr.show = mspro_block_attr_show(s_attr->id);

    if (!rc)
    continue;

    - msb->attributes[cnt].size = rc;
    - msb->attributes[cnt].data = kmalloc(rc, GFP_KERNEL);
    - if (!msb->attributes[cnt].data) {
    + s_attr->size = rc;
    + s_attr->data = kmalloc(rc, GFP_KERNEL);
    + if (!s_attr->data) {
    rc = -ENOMEM;
    goto out_free_buffer;
    }
    @@ -931,8 +910,7 @@ static int mspro_block_read_attributes(struct memstick_dev *card)
    == be32_to_cpu(param.data_address))
    && (((addr + rc - 1) / msb->page_size)
    == be32_to_cpu(param.data_address))) {
    - memcpy(msb->attributes[cnt].data,
    - buffer + addr % msb->page_size,
    + memcpy(s_attr->data, buffer + addr % msb->page_size,
    rc);
    continue;
    }
    @@ -948,12 +926,10 @@ static int mspro_block_read_attributes(struct memstick_dev *card)
    }
    }

    - param = (struct mspro_param_register){
    - .system = msb->system,
    - .data_count = cpu_to_be16((rc / msb->page_size) + 1),
    - .data_address = cpu_to_be32(addr / msb->page_size),
    - .cmd_param = 0
    - };
    + param.system = msb->system;
    + param.data_count = cpu_to_be16((rc / msb->page_size) + 1);
    + param.data_address = cpu_to_be32(addr / msb->page_size);
    + param.cmd_param = 0;

    sg_init_one(&msb->req_sg[0], buffer,
    be16_to_cpu(param.data_count) * msb->page_size);
    @@ -978,9 +954,7 @@ static int mspro_block_read_attributes(struct memstick_dev *card)
    goto out_free_buffer;
    }

    - memcpy(msb->attributes[cnt].data,
    - buffer + addr % msb->page_size,
    - rc);
    + memcpy(s_attr->data, buffer + addr % msb->page_size, rc);
    }

    rc = 0;
    @@ -998,12 +972,10 @@ static int mspro_block_init_card(struct memstick_dev *card)
    int rc = 0;

    msb->system = 0x80;
    - card->reg_addr = (struct ms_register_addr){
    - offsetof(struct mspro_register, status),
    - sizeof(struct ms_status_register),
    - offsetof(struct mspro_register, param),
    - sizeof(struct mspro_param_register)
    - };
    + card->reg_addr.r_offset = offsetof(struct mspro_register, status);
    + card->reg_addr.r_length = sizeof(struct ms_status_register);
    + card->reg_addr.w_offset = offsetof(struct mspro_register, param);
    + card->reg_addr.w_length = sizeof(struct mspro_param_register);

    if (memstick_set_rw_addr(card))
    return -EIO;
    @@ -1046,6 +1018,7 @@ static int mspro_block_init_disk(struct memstick_dev *card)
    struct memstick_host *host = card->host;
    struct mspro_devinfo *dev_info = NULL;
    struct mspro_sys_info *sys_info = NULL;
    + struct mspro_sys_attr *s_attr = NULL;
    int rc, disk_id;
    u64 limit = BLK_BOUNCE_HIGH;
    unsigned long capacity;
    @@ -1053,13 +1026,13 @@ static int mspro_block_init_disk(struct memstick_dev *card)
    if (host->cdev.dev->dma_mask && *(host->cdev.dev->dma_mask))
    limit = *(host->cdev.dev->dma_mask);

    - for (rc = 0; rc < msb->attr_count; rc++) {
    - if (msb->attributes[rc].id == MSPRO_BLOCK_ID_DEVINFO)
    - dev_info = (struct mspro_devinfo *)msb->attributes[rc]
    - .data;
    - if (msb->attributes[rc].id == MSPRO_BLOCK_ID_SYSINFO)
    - sys_info = (struct mspro_sys_info *)msb->attributes[rc]
    - .data;
    + for (rc = 0; msb->attr_group.attrs[rc]; ++rc) {
    + s_attr = mspro_from_sysfs_attr(msb->attr_group.attrs[rc]);
    +
    + if (s_attr->id == MSPRO_BLOCK_ID_DEVINFO)
    + dev_info = s_attr->data;
    + else if (s_attr->id == MSPRO_BLOCK_ID_SYSINFO)
    + sys_info = s_attr->data;
    }

    if (!dev_info || !sys_info)
    @@ -1150,11 +1123,18 @@ out_release_id:
    static void mspro_block_data_clear(struct mspro_block_data *msb)
    {
    int cnt;
    + struct mspro_sys_attr *s_attr;
    +
    + if (msb->attr_group.attrs) {
    + for (cnt = 0; msb->attr_group.attrs[cnt]; ++cnt) {
    + s_attr = mspro_from_sysfs_attr(msb->attr_group
    + .attrs[cnt]);
    + kfree(s_attr->data);
    + kfree(s_attr);
    + }
    + kfree(msb->attr_group.attrs);
    + }

    - for (cnt = 0; cnt < msb->attr_count; cnt++)
    - kfree(msb->attributes[cnt].data);
    -
    - kfree(msb->attributes);
    msb->card = NULL;
    }

    @@ -1181,7 +1161,7 @@ static int mspro_block_probe(struct memstick_dev *card)
    if (rc)
    goto out_free;

    - rc = mspro_block_sysfs_register(card);
    + rc = sysfs_create_group(&card->dev.kobj, &msb->attr_group);
    if (rc)
    goto out_free;

    @@ -1191,7 +1171,7 @@ static int mspro_block_probe(struct memstick_dev *card)
    return 0;
    }

    - mspro_block_sysfs_unregister(card);
    + sysfs_remove_group(&card->dev.kobj, &msb->attr_group);
    out_free:
    memstick_set_drvdata(card, NULL);
    mspro_block_data_clear(msb);
    @@ -1223,7 +1203,7 @@ static void mspro_block_remove(struct memstick_dev *card)

    blk_cleanup_queue(msb->queue);

    - mspro_block_sysfs_unregister(card);
    + sysfs_remove_group(&card->dev.kobj, &msb->attr_group);

    mutex_lock(&mspro_block_disk_lock);
    mspro_block_data_clear(msb);
    @@ -1264,6 +1244,7 @@ static int mspro_block_resume(struct memstick_dev *card)

    struct mspro_block_data *new_msb;
    struct memstick_host *host = card->host;
    + struct mspro_sys_attr s_attr, r_attr;
    unsigned char cnt;

    mutex_lock(&host->lock);
    @@ -1278,13 +1259,18 @@ static int mspro_block_resume(struct memstick_dev *card)
    if (mspro_block_init_card(card))
    goto out_free;

    - for (cnt = 0; cnt < new_msb->attr_count; cnt++) {
    - if (new_msb->attributes[cnt].id == MSPRO_BLOCK_ID_SYSINFO
    - && cnt < msb->attr_count
    - && msb->attributes[cnt].id == MSPRO_BLOCK_ID_SYSINFO) {
    - if (memcmp(new_msb->attributes[cnt].data,
    - msb->attributes[cnt].data,
    - msb->attributes[cnt].size))
    + for (cnt = 0; new_msb->attr_group.attrs[cnt]
    + && msb->attr_group.attrs[cnt]; ++cnt) {
    + s_attr = container_of(new_msb->attr_group.attrs[cnt],
    + struct mspro_sys_attr,
    + dev_attr);
    + r_attr = container_of(msb->attr_group.attrs[cnt],
    + struct mspro_sys_attr,
    + dev_attr);
    +
    + if (s_attr->id == MSPRO_BLOCK_ID_SYSINFO
    + && r_attr->id == s_attr->id) {
    + if (memcmp(s_attr->data, r_attr->data, s_attr->size))
    break;

    memstick_set_drvdata(card, msb);
    diff --git a/include/linux/memstick.h b/include/linux/memstick.h
    index dc5ac9d..334d059 100644
    --- a/include/linux/memstick.h
    +++ b/include/linux/memstick.h
    @@ -13,6 +13,10 @@
    #define _MEMSTICK_H

    #include <linux/workqueue.h>
    +#include <linux/scatterlist.h>
    +#include <linux/device.h>
    +
    +/*** Hardware based structures ***/

    struct ms_status_register {
    unsigned char reserved;
    @@ -151,6 +155,8 @@ enum {
    */
    };

    +/*** Driver structures and functions ***/
    +
    #define MEMSTICK_PART_SHIFT 3

    enum memstick_param { MEMSTICK_POWER = 1, MEMSTICK_INTERFACE };
    @@ -212,7 +218,9 @@ struct memstick_dev {
    struct completion mrq_complete;
    struct memstick_request current_mrq;

    + /* Check that media driver is still willing to operate the device. */
    int (*check)(struct memstick_dev *card);
    + /* Get next request from the media driver. */
    int (*next_request)(struct memstick_dev *card,
    struct memstick_request **mrq);

    @@ -232,7 +240,9 @@ struct memstick_host {
    struct memstick_dev *card;
    unsigned int retries;

    + /* Notify the host that some requests are pending. */
    void (*request)(struct memstick_host *host);
    + /* Set host IO parameters (power, clock, etc). */
    void (*set_param)(struct memstick_host *host,
    enum memstick_param param,
    int value);
    @@ -271,17 +281,17 @@ void memstick_new_req(struct memstick_host *host);

    int memstick_set_rw_addr(struct memstick_dev *card);

    -inline void *memstick_priv(struct memstick_host *host)
    +static inline void *memstick_priv(struct memstick_host *host)
    {
    return (void *)host->private;
    }

    -inline void *memstick_get_drvdata(struct memstick_dev *card)
    +static inline void *memstick_get_drvdata(struct memstick_dev *card)
    {
    return dev_get_drvdata(&card->dev);
    }

    -inline void memstick_set_drvdata(struct memstick_dev *card, void *data)
    +static inline void memstick_set_drvdata(struct memstick_dev *card, void *data)
    {
    dev_set_drvdata(&card->dev, data);
    }


    ____________________________________________________________________________________
    Be a better friend, newshound, and
    know-it-all with Yahoo! Mobile. Try it now. http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ


    \
     
     \ /
      Last update: 2008-01-25 09:07    [W:0.078 / U:6.204 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site