diff options
Diffstat (limited to 'drivers/block')
-rw-r--r-- | drivers/block/aoe/aoe.h | 2 | ||||
-rw-r--r-- | drivers/block/aoe/aoechr.c | 2 | ||||
-rw-r--r-- | drivers/block/aoe/aoecmd.c | 15 | ||||
-rw-r--r-- | drivers/block/genhd.c | 25 | ||||
-rw-r--r-- | drivers/block/paride/pg.c | 2 | ||||
-rw-r--r-- | drivers/block/paride/pt.c | 4 | ||||
-rw-r--r-- | drivers/block/sx8.c | 51 |
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 | ||
340 | static 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 | |||
340 | static struct sysfs_ops disk_sysfs_ops = { | 353 | static 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 | ||
358 | static 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 | } | ||
344 | static ssize_t disk_dev_read(struct gendisk * disk, char *page) | 364 | static 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 | } |
405 | static struct disk_attribute disk_attr_uevent = { | ||
406 | .attr = {.name = "uevent", .mode = S_IWUSR }, | ||
407 | .store = disk_uevent_store | ||
408 | }; | ||
385 | static struct disk_attribute disk_attr_dev = { | 409 | static 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 | ||
406 | static struct attribute * default_attrs[] = { | 430 | static 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 | ||
34 | MODULE_AUTHOR("Jeff Garzik"); | ||
35 | MODULE_LICENSE("GPL"); | ||
36 | MODULE_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 | ||
47 | MODULE_AUTHOR("Jeff Garzik"); | ||
48 | MODULE_LICENSE("GPL"); | ||
49 | MODULE_DESCRIPTION("Promise SATA SX8 block driver"); | ||
50 | MODULE_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 | */ | ||
68 | static int max_queue = 1; | ||
69 | module_param(max_queue, int, 0444); | ||
70 | MODULE_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 | ||
204 | enum { | ||
205 | CARM_SG_BOUNDARY = 0xffffUL, /* s/g segment boundary */ | ||
206 | }; | ||
207 | |||
184 | enum scatter_gather_types { | 208 | enum 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 | ||
219 | struct carm_port { | 243 | struct 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 | ||
529 | static int carm_put_request(struct carm_host *host, struct carm_request *crq) | 552 | static 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)) { |