aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/aoe/aoe.h2
-rw-r--r--drivers/block/aoe/aoechr.c2
-rw-r--r--drivers/block/aoe/aoecmd.c15
-rw-r--r--drivers/block/genhd.c25
-rw-r--r--drivers/block/paride/pg.c2
-rw-r--r--drivers/block/paride/pt.c4
-rw-r--r--drivers/block/sx8.c51
7 files changed, 75 insertions, 26 deletions
diff --git a/drivers/block/aoe/aoe.h b/drivers/block/aoe/aoe.h
index 0e9e586e9ba3..881c48d941b7 100644
--- a/drivers/block/aoe/aoe.h
+++ b/drivers/block/aoe/aoe.h
@@ -1,5 +1,5 @@
1/* Copyright (c) 2004 Coraid, Inc. See COPYING for GPL terms. */ 1/* Copyright (c) 2004 Coraid, Inc. See COPYING for GPL terms. */
2#define VERSION "12" 2#define VERSION "14"
3#define AOE_MAJOR 152 3#define AOE_MAJOR 152
4#define DEVICE_NAME "aoe" 4#define DEVICE_NAME "aoe"
5 5
diff --git a/drivers/block/aoe/aoechr.c b/drivers/block/aoe/aoechr.c
index 45a243096187..41ae0ede619a 100644
--- a/drivers/block/aoe/aoechr.c
+++ b/drivers/block/aoe/aoechr.c
@@ -224,7 +224,7 @@ aoechr_init(void)
224 return PTR_ERR(aoe_class); 224 return PTR_ERR(aoe_class);
225 } 225 }
226 for (i = 0; i < ARRAY_SIZE(chardevs); ++i) 226 for (i = 0; i < ARRAY_SIZE(chardevs); ++i)
227 class_device_create(aoe_class, 227 class_device_create(aoe_class, NULL,
228 MKDEV(AOE_MAJOR, chardevs[i].minor), 228 MKDEV(AOE_MAJOR, chardevs[i].minor),
229 NULL, chardevs[i].name); 229 NULL, chardevs[i].name);
230 230
diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c
index b5be4b7d7b5b..5c9c7c1a3d4c 100644
--- a/drivers/block/aoe/aoecmd.c
+++ b/drivers/block/aoe/aoecmd.c
@@ -8,6 +8,7 @@
8#include <linux/blkdev.h> 8#include <linux/blkdev.h>
9#include <linux/skbuff.h> 9#include <linux/skbuff.h>
10#include <linux/netdevice.h> 10#include <linux/netdevice.h>
11#include <asm/unaligned.h>
11#include "aoe.h" 12#include "aoe.h"
12 13
13#define TIMERTICK (HZ / 10) 14#define TIMERTICK (HZ / 10)
@@ -311,16 +312,16 @@ ataid_complete(struct aoedev *d, unsigned char *id)
311 u16 n; 312 u16 n;
312 313
313 /* word 83: command set supported */ 314 /* word 83: command set supported */
314 n = le16_to_cpup((__le16 *) &id[83<<1]); 315 n = le16_to_cpu(get_unaligned((__le16 *) &id[83<<1]));
315 316
316 /* word 86: command set/feature enabled */ 317 /* word 86: command set/feature enabled */
317 n |= le16_to_cpup((__le16 *) &id[86<<1]); 318 n |= le16_to_cpu(get_unaligned((__le16 *) &id[86<<1]));
318 319
319 if (n & (1<<10)) { /* bit 10: LBA 48 */ 320 if (n & (1<<10)) { /* bit 10: LBA 48 */
320 d->flags |= DEVFL_EXT; 321 d->flags |= DEVFL_EXT;
321 322
322 /* word 100: number lba48 sectors */ 323 /* word 100: number lba48 sectors */
323 ssize = le64_to_cpup((__le64 *) &id[100<<1]); 324 ssize = le64_to_cpu(get_unaligned((__le64 *) &id[100<<1]));
324 325
325 /* set as in ide-disk.c:init_idedisk_capacity */ 326 /* set as in ide-disk.c:init_idedisk_capacity */
326 d->geo.cylinders = ssize; 327 d->geo.cylinders = ssize;
@@ -331,12 +332,12 @@ ataid_complete(struct aoedev *d, unsigned char *id)
331 d->flags &= ~DEVFL_EXT; 332 d->flags &= ~DEVFL_EXT;
332 333
333 /* number lba28 sectors */ 334 /* number lba28 sectors */
334 ssize = le32_to_cpup((__le32 *) &id[60<<1]); 335 ssize = le32_to_cpu(get_unaligned((__le32 *) &id[60<<1]));
335 336
336 /* NOTE: obsolete in ATA 6 */ 337 /* NOTE: obsolete in ATA 6 */
337 d->geo.cylinders = le16_to_cpup((__le16 *) &id[54<<1]); 338 d->geo.cylinders = le16_to_cpu(get_unaligned((__le16 *) &id[54<<1]));
338 d->geo.heads = le16_to_cpup((__le16 *) &id[55<<1]); 339 d->geo.heads = le16_to_cpu(get_unaligned((__le16 *) &id[55<<1]));
339 d->geo.sectors = le16_to_cpup((__le16 *) &id[56<<1]); 340 d->geo.sectors = le16_to_cpu(get_unaligned((__le16 *) &id[56<<1]));
340 } 341 }
341 d->ssize = ssize; 342 d->ssize = ssize;
342 d->geo.start = 0; 343 d->geo.start = 0;
diff --git a/drivers/block/genhd.c b/drivers/block/genhd.c
index d42840cc0d1d..486ce1fdeb8c 100644
--- a/drivers/block/genhd.c
+++ b/drivers/block/genhd.c
@@ -337,10 +337,30 @@ static ssize_t disk_attr_show(struct kobject *kobj, struct attribute *attr,
337 return ret; 337 return ret;
338} 338}
339 339
340static ssize_t disk_attr_store(struct kobject * kobj, struct attribute * attr,
341 const char *page, size_t count)
342{
343 struct gendisk *disk = to_disk(kobj);
344 struct disk_attribute *disk_attr =
345 container_of(attr,struct disk_attribute,attr);
346 ssize_t ret = 0;
347
348 if (disk_attr->store)
349 ret = disk_attr->store(disk, page, count);
350 return ret;
351}
352
340static struct sysfs_ops disk_sysfs_ops = { 353static struct sysfs_ops disk_sysfs_ops = {
341 .show = &disk_attr_show, 354 .show = &disk_attr_show,
355 .store = &disk_attr_store,
342}; 356};
343 357
358static ssize_t disk_uevent_store(struct gendisk * disk,
359 const char *buf, size_t count)
360{
361 kobject_hotplug(&disk->kobj, KOBJ_ADD);
362 return count;
363}
344static ssize_t disk_dev_read(struct gendisk * disk, char *page) 364static ssize_t disk_dev_read(struct gendisk * disk, char *page)
345{ 365{
346 dev_t base = MKDEV(disk->major, disk->first_minor); 366 dev_t base = MKDEV(disk->major, disk->first_minor);
@@ -382,6 +402,10 @@ static ssize_t disk_stats_read(struct gendisk * disk, char *page)
382 jiffies_to_msecs(disk_stat_read(disk, io_ticks)), 402 jiffies_to_msecs(disk_stat_read(disk, io_ticks)),
383 jiffies_to_msecs(disk_stat_read(disk, time_in_queue))); 403 jiffies_to_msecs(disk_stat_read(disk, time_in_queue)));
384} 404}
405static struct disk_attribute disk_attr_uevent = {
406 .attr = {.name = "uevent", .mode = S_IWUSR },
407 .store = disk_uevent_store
408};
385static struct disk_attribute disk_attr_dev = { 409static struct disk_attribute disk_attr_dev = {
386 .attr = {.name = "dev", .mode = S_IRUGO }, 410 .attr = {.name = "dev", .mode = S_IRUGO },
387 .show = disk_dev_read 411 .show = disk_dev_read
@@ -404,6 +428,7 @@ static struct disk_attribute disk_attr_stat = {
404}; 428};
405 429
406static struct attribute * default_attrs[] = { 430static struct attribute * default_attrs[] = {
431 &disk_attr_uevent.attr,
407 &disk_attr_dev.attr, 432 &disk_attr_dev.attr,
408 &disk_attr_range.attr, 433 &disk_attr_range.attr,
409 &disk_attr_removable.attr, 434 &disk_attr_removable.attr,
diff --git a/drivers/block/paride/pg.c b/drivers/block/paride/pg.c
index b3982395f22b..82f2d6d2eeef 100644
--- a/drivers/block/paride/pg.c
+++ b/drivers/block/paride/pg.c
@@ -674,7 +674,7 @@ static int __init pg_init(void)
674 for (unit = 0; unit < PG_UNITS; unit++) { 674 for (unit = 0; unit < PG_UNITS; unit++) {
675 struct pg *dev = &devices[unit]; 675 struct pg *dev = &devices[unit];
676 if (dev->present) { 676 if (dev->present) {
677 class_device_create(pg_class, MKDEV(major, unit), 677 class_device_create(pg_class, NULL, MKDEV(major, unit),
678 NULL, "pg%u", unit); 678 NULL, "pg%u", unit);
679 err = devfs_mk_cdev(MKDEV(major, unit), 679 err = devfs_mk_cdev(MKDEV(major, unit),
680 S_IFCHR | S_IRUSR | S_IWUSR, "pg/%u", 680 S_IFCHR | S_IRUSR | S_IWUSR, "pg/%u",
diff --git a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c
index d8d35233cf49..686c95573452 100644
--- a/drivers/block/paride/pt.c
+++ b/drivers/block/paride/pt.c
@@ -971,7 +971,7 @@ static int __init pt_init(void)
971 devfs_mk_dir("pt"); 971 devfs_mk_dir("pt");
972 for (unit = 0; unit < PT_UNITS; unit++) 972 for (unit = 0; unit < PT_UNITS; unit++)
973 if (pt[unit].present) { 973 if (pt[unit].present) {
974 class_device_create(pt_class, MKDEV(major, unit), 974 class_device_create(pt_class, NULL, MKDEV(major, unit),
975 NULL, "pt%d", unit); 975 NULL, "pt%d", unit);
976 err = devfs_mk_cdev(MKDEV(major, unit), 976 err = devfs_mk_cdev(MKDEV(major, unit),
977 S_IFCHR | S_IRUSR | S_IWUSR, 977 S_IFCHR | S_IRUSR | S_IWUSR,
@@ -980,7 +980,7 @@ static int __init pt_init(void)
980 class_device_destroy(pt_class, MKDEV(major, unit)); 980 class_device_destroy(pt_class, MKDEV(major, unit));
981 goto out_class; 981 goto out_class;
982 } 982 }
983 class_device_create(pt_class, MKDEV(major, unit + 128), 983 class_device_create(pt_class, NULL, MKDEV(major, unit + 128),
984 NULL, "pt%dn", unit); 984 NULL, "pt%dn", unit);
985 err = devfs_mk_cdev(MKDEV(major, unit + 128), 985 err = devfs_mk_cdev(MKDEV(major, unit + 128),
986 S_IFCHR | S_IRUSR | S_IWUSR, 986 S_IFCHR | S_IRUSR | S_IWUSR,
diff --git a/drivers/block/sx8.c b/drivers/block/sx8.c
index d57007b92f77..1ded3b433459 100644
--- a/drivers/block/sx8.c
+++ b/drivers/block/sx8.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * sx8.c: Driver for Promise SATA SX8 looks-like-I2O hardware 2 * sx8.c: Driver for Promise SATA SX8 looks-like-I2O hardware
3 * 3 *
4 * Copyright 2004 Red Hat, Inc. 4 * Copyright 2004-2005 Red Hat, Inc.
5 * 5 *
6 * Author/maintainer: Jeff Garzik <jgarzik@pobox.com> 6 * Author/maintainer: Jeff Garzik <jgarzik@pobox.com>
7 * 7 *
@@ -31,10 +31,6 @@
31#include <asm/semaphore.h> 31#include <asm/semaphore.h>
32#include <asm/uaccess.h> 32#include <asm/uaccess.h>
33 33
34MODULE_AUTHOR("Jeff Garzik");
35MODULE_LICENSE("GPL");
36MODULE_DESCRIPTION("Promise SATA SX8 block driver");
37
38#if 0 34#if 0
39#define CARM_DEBUG 35#define CARM_DEBUG
40#define CARM_VERBOSE_DEBUG 36#define CARM_VERBOSE_DEBUG
@@ -45,9 +41,35 @@ MODULE_DESCRIPTION("Promise SATA SX8 block driver");
45#undef CARM_NDEBUG 41#undef CARM_NDEBUG
46 42
47#define DRV_NAME "sx8" 43#define DRV_NAME "sx8"
48#define DRV_VERSION "0.8" 44#define DRV_VERSION "1.0"
49#define PFX DRV_NAME ": " 45#define PFX DRV_NAME ": "
50 46
47MODULE_AUTHOR("Jeff Garzik");
48MODULE_LICENSE("GPL");
49MODULE_DESCRIPTION("Promise SATA SX8 block driver");
50MODULE_VERSION(DRV_VERSION);
51
52/*
53 * SX8 hardware has a single message queue for all ATA ports.
54 * When this driver was written, the hardware (firmware?) would
55 * corrupt data eventually, if more than one request was outstanding.
56 * As one can imagine, having 8 ports bottlenecking on a single
57 * command hurts performance.
58 *
59 * Based on user reports, later versions of the hardware (firmware?)
60 * seem to be able to survive with more than one command queued.
61 *
62 * Therefore, we default to the safe option -- 1 command -- but
63 * allow the user to increase this.
64 *
65 * SX8 should be able to support up to ~60 queued commands (CARM_MAX_REQ),
66 * but problems seem to occur when you exceed ~30, even on newer hardware.
67 */
68static int max_queue = 1;
69module_param(max_queue, int, 0444);
70MODULE_PARM_DESC(max_queue, "Maximum number of queued commands. (min==1, max==30, safe==1)");
71
72
51#define NEXT_RESP(idx) ((idx + 1) % RMSG_Q_LEN) 73#define NEXT_RESP(idx) ((idx + 1) % RMSG_Q_LEN)
52 74
53/* 0xf is just arbitrary, non-zero noise; this is sorta like poisoning */ 75/* 0xf is just arbitrary, non-zero noise; this is sorta like poisoning */
@@ -90,12 +112,10 @@ enum {
90 112
91 /* command message queue limits */ 113 /* command message queue limits */
92 CARM_MAX_REQ = 64, /* max command msgs per host */ 114 CARM_MAX_REQ = 64, /* max command msgs per host */
93 CARM_MAX_Q = 1, /* one command at a time */
94 CARM_MSG_LOW_WATER = (CARM_MAX_REQ / 4), /* refill mark */ 115 CARM_MSG_LOW_WATER = (CARM_MAX_REQ / 4), /* refill mark */
95 116
96 /* S/G limits, host-wide and per-request */ 117 /* S/G limits, host-wide and per-request */
97 CARM_MAX_REQ_SG = 32, /* max s/g entries per request */ 118 CARM_MAX_REQ_SG = 32, /* max s/g entries per request */
98 CARM_SG_BOUNDARY = 0xffffUL, /* s/g segment boundary */
99 CARM_MAX_HOST_SG = 600, /* max s/g entries per host */ 119 CARM_MAX_HOST_SG = 600, /* max s/g entries per host */
100 CARM_SG_LOW_WATER = (CARM_MAX_HOST_SG / 4), /* re-fill mark */ 120 CARM_SG_LOW_WATER = (CARM_MAX_HOST_SG / 4), /* re-fill mark */
101 121
@@ -181,6 +201,10 @@ enum {
181 FL_DYN_MAJOR = (1 << 17), 201 FL_DYN_MAJOR = (1 << 17),
182}; 202};
183 203
204enum {
205 CARM_SG_BOUNDARY = 0xffffUL, /* s/g segment boundary */
206};
207
184enum scatter_gather_types { 208enum scatter_gather_types {
185 SGT_32BIT = 0, 209 SGT_32BIT = 0,
186 SGT_64BIT = 1, 210 SGT_64BIT = 1,
@@ -218,7 +242,6 @@ static const char *state_name[] = {
218 242
219struct carm_port { 243struct carm_port {
220 unsigned int port_no; 244 unsigned int port_no;
221 unsigned int n_queued;
222 struct gendisk *disk; 245 struct gendisk *disk;
223 struct carm_host *host; 246 struct carm_host *host;
224 247
@@ -448,7 +471,7 @@ static inline int carm_lookup_bucket(u32 msg_size)
448 for (i = 0; i < ARRAY_SIZE(msg_sizes); i++) 471 for (i = 0; i < ARRAY_SIZE(msg_sizes); i++)
449 if (msg_size <= msg_sizes[i]) 472 if (msg_size <= msg_sizes[i])
450 return i; 473 return i;
451 474
452 return -ENOENT; 475 return -ENOENT;
453} 476}
454 477
@@ -509,7 +532,7 @@ static struct carm_request *carm_get_request(struct carm_host *host)
509 if (host->hw_sg_used >= (CARM_MAX_HOST_SG - CARM_MAX_REQ_SG)) 532 if (host->hw_sg_used >= (CARM_MAX_HOST_SG - CARM_MAX_REQ_SG))
510 return NULL; 533 return NULL;
511 534
512 for (i = 0; i < CARM_MAX_Q; i++) 535 for (i = 0; i < max_queue; i++)
513 if ((host->msg_alloc & (1ULL << i)) == 0) { 536 if ((host->msg_alloc & (1ULL << i)) == 0) {
514 struct carm_request *crq = &host->req[i]; 537 struct carm_request *crq = &host->req[i];
515 crq->port = NULL; 538 crq->port = NULL;
@@ -521,14 +544,14 @@ static struct carm_request *carm_get_request(struct carm_host *host)
521 assert(host->n_msgs <= CARM_MAX_REQ); 544 assert(host->n_msgs <= CARM_MAX_REQ);
522 return crq; 545 return crq;
523 } 546 }
524 547
525 DPRINTK("no request available, returning NULL\n"); 548 DPRINTK("no request available, returning NULL\n");
526 return NULL; 549 return NULL;
527} 550}
528 551
529static int carm_put_request(struct carm_host *host, struct carm_request *crq) 552static int carm_put_request(struct carm_host *host, struct carm_request *crq)
530{ 553{
531 assert(crq->tag < CARM_MAX_Q); 554 assert(crq->tag < max_queue);
532 555
533 if (unlikely((host->msg_alloc & (1ULL << crq->tag)) == 0)) 556 if (unlikely((host->msg_alloc & (1ULL << crq->tag)) == 0))
534 return -EINVAL; /* tried to clear a tag that was not active */ 557 return -EINVAL; /* tried to clear a tag that was not active */
@@ -791,7 +814,7 @@ static inline void carm_end_rq(struct carm_host *host, struct carm_request *crq,
791 int is_ok) 814 int is_ok)
792{ 815{
793 carm_end_request_queued(host, crq, is_ok); 816 carm_end_request_queued(host, crq, is_ok);
794 if (CARM_MAX_Q == 1) 817 if (max_queue == 1)
795 carm_round_robin(host); 818 carm_round_robin(host);
796 else if ((host->n_msgs <= CARM_MSG_LOW_WATER) && 819 else if ((host->n_msgs <= CARM_MSG_LOW_WATER) &&
797 (host->hw_sg_used <= CARM_SG_LOW_WATER)) { 820 (host->hw_sg_used <= CARM_SG_LOW_WATER)) {