All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alex Dubov <oakad@yahoo.com>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: linux-kernel@vger.kernel.org
Subject: [PATCH] [MEMSTICK] Updates for the memstick driver
Date: Thu, 24 Jan 2008 23:58:52 -0800 (PST)	[thread overview]
Message-ID: <439089.5370.qm@web36701.mail.mud.yahoo.com> (raw)
In-Reply-To: <20080122105900.c7ea1cc3.akpm@linux-foundation.org>

* 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 


  reply	other threads:[~2008-01-25  8:02 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-01-02  6:42 [PATCH] [MEMSTICK] Initial commit for Sony MemoryStick support oakad
2008-01-10  9:00 ` Andrew Morton
2008-01-11 12:14   ` Jens Axboe
2008-01-14  3:26   ` Alex Dubov
2008-01-22 16:12   ` Alex Dubov
2008-01-22 18:59     ` Andrew Morton
2008-01-25  7:58       ` Alex Dubov [this message]
2008-01-27  6:01         ` [PATCH] [MEMSTICK] Updates for the memstick driver Andrew Morton
2008-02-03  0:16         ` Andrew Morton
2008-02-04  4:31           ` [PATCH] memstick: use __blk_end_request to complete requests Alex Dubov
2008-02-04  7:07             ` Andrew Morton
2008-02-09 14:59               ` [PATCH] memstick: fix attribute structure casting in mspro_block_resume Alex Dubov
2008-01-15 17:21 ` [PATCH] [MEMSTICK] Initial commit for Sony MemoryStick support Mariusz Kozlowski
2008-01-16  1:52   ` Alex Dubov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=439089.5370.qm@web36701.mail.mud.yahoo.com \
    --to=oakad@yahoo.com \
    --cc=akpm@linux-foundation.org \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.