lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Thu, 24 Jan 2008 23:58:52 -0800 (PST)
From:	Alex Dubov <oakad@...oo.com>
To:	Andrew Morton <akpm@...ux-foundation.org>
Cc:	linux-kernel@...r.kernel.org
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 

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ