The patch titled
     memstick: updates for the memstick driver
has been added to the -mm tree.  Its filename is
     updates-for-the-memstick-driver.patch

Before you just go and hit "reply", please:
   a) Consider who else should be cc'ed
   b) Prefer to cc a suitable mailing list as well
   c) Ideally: find the original patch on the mailing list and do a
      reply-to-all to that, adding suitable additional cc's

*** Remember to use Documentation/SubmitChecklist when testing your code ***

See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find
out what to do about this

The current -mm tree may be found at http://userweb.kernel.org/~akpm/mmotm/

------------------------------------------------------
Subject: memstick: updates for the memstick driver
From: Alex Dubov <[EMAIL PROTECTED]>

* 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


Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
---

 drivers/memstick/core/memstick.c    |   91 ++++-
 drivers/memstick/core/mspro_block.c |  422 ++++++++++++--------------
 include/linux/memstick.h            |   10 
 3 files changed, 288 insertions(+), 235 deletions(-)

diff -puN drivers/memstick/core/memstick.c~updates-for-the-memstick-driver 
drivers/memstick/core/memstick.c
--- a/drivers/memstick/core/memstick.c~updates-for-the-memstick-driver
+++ a/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 
                                                   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 m
        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_ho
 }
 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_ho
 }
 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 memstic
 }
 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_r
 }
 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
        } 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_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_all
                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_s
        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_hos
 }
 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_ho
 }
 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 memstic
 }
 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 -puN drivers/memstick/core/mspro_block.c~updates-for-the-memstick-driver 
drivers/memstick/core/mspro_block.c
--- a/drivers/memstick/core/mspro_block.c~updates-for-the-memstick-driver
+++ a/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
 
 /*** 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_def
                                             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_sys
 {
        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_mod
                                               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 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_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_sho
        }
 }
 
-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(
 
                        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 r
        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_paralle
        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(s
                .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(s
        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(s
        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(s
                     == 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(s
                        }
                }
 
-               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(s
                        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 
        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 
        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 
        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;
 
-       for (cnt = 0; cnt < msb->attr_count; cnt++)
-               kfree(msb->attributes[cnt].data);
+       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);
+       }
 
-       kfree(msb->attributes);
        msb->card = NULL;
 }
 
@@ -1181,7 +1161,7 @@ static int mspro_block_probe(struct mems
        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 mems
                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 me
 
        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 mem
 
        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 mem
        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 -puN include/linux/memstick.h~updates-for-the-memstick-driver 
include/linux/memstick.h
--- a/include/linux/memstick.h~updates-for-the-memstick-driver
+++ a/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);
_

Patches currently in -mm which might be from [EMAIL PROTECTED] are

memstick-initial-commit-for-sony-memorystick-support.patch
memstick-initial-commit-for-sony-memorystick-support-fix-2.patch
updates-for-the-memstick-driver.patch

-
To unsubscribe from this list: send the line "unsubscribe mm-commits" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to