aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/mtip32xx
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-05-08 14:51:05 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-05-08 14:51:05 -0400
commitebb37277796269da36a8bc5d72ed1e8e1fb7d34b (patch)
tree0ded627a62a5cec70b18d12825dd858855c135d3 /drivers/block/mtip32xx
parent4de13d7aa8f4d02f4dc99d4609575659f92b3c5a (diff)
parentf50efd2fdbd9b35b11f5778ed85beb764184bda9 (diff)
Merge branch 'for-3.10/drivers' of git://git.kernel.dk/linux-block
Pull block driver updates from Jens Axboe: "It might look big in volume, but when categorized, not a lot of drivers are touched. The pull request contains: - mtip32xx fixes from Micron. - A slew of drbd updates, this time in a nicer series. - bcache, a flash/ssd caching framework from Kent. - Fixes for cciss" * 'for-3.10/drivers' of git://git.kernel.dk/linux-block: (66 commits) bcache: Use bd_link_disk_holder() bcache: Allocator cleanup/fixes cciss: bug fix to prevent cciss from loading in kdump crash kernel cciss: add cciss_allow_hpsa module parameter drivers/block/mg_disk.c: add CONFIG_PM_SLEEP to suspend/resume functions mtip32xx: Workaround for unaligned writes bcache: Make sure blocksize isn't smaller than device blocksize bcache: Fix merge_bvec_fn usage for when it modifies the bvm bcache: Correctly check against BIO_MAX_PAGES bcache: Hack around stuff that clones up to bi_max_vecs bcache: Set ra_pages based on backing device's ra_pages bcache: Take data offset from the bdev superblock. mtip32xx: mtip32xx: Disable TRIM support mtip32xx: fix a smatch warning bcache: Disable broken btree fuzz tester bcache: Fix a format string overflow bcache: Fix a minor memory leak on device teardown bcache: Documentation updates bcache: Use WARN_ONCE() instead of __WARN() bcache: Add missing #include <linux/prefetch.h> ...
Diffstat (limited to 'drivers/block/mtip32xx')
-rw-r--r--drivers/block/mtip32xx/mtip32xx.c79
-rw-r--r--drivers/block/mtip32xx/mtip32xx.h11
2 files changed, 68 insertions, 22 deletions
diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c
index 32c678028e53..847107ef0cce 100644
--- a/drivers/block/mtip32xx/mtip32xx.c
+++ b/drivers/block/mtip32xx/mtip32xx.c
@@ -728,7 +728,10 @@ static void mtip_async_complete(struct mtip_port *port,
728 atomic_set(&port->commands[tag].active, 0); 728 atomic_set(&port->commands[tag].active, 0);
729 release_slot(port, tag); 729 release_slot(port, tag);
730 730
731 up(&port->cmd_slot); 731 if (unlikely(command->unaligned))
732 up(&port->cmd_slot_unal);
733 else
734 up(&port->cmd_slot);
732} 735}
733 736
734/* 737/*
@@ -1560,10 +1563,12 @@ static int mtip_get_identify(struct mtip_port *port, void __user *user_buffer)
1560 } 1563 }
1561#endif 1564#endif
1562 1565
1566#ifdef MTIP_TRIM /* Disabling TRIM support temporarily */
1563 /* Demux ID.DRAT & ID.RZAT to determine trim support */ 1567 /* Demux ID.DRAT & ID.RZAT to determine trim support */
1564 if (port->identify[69] & (1 << 14) && port->identify[69] & (1 << 5)) 1568 if (port->identify[69] & (1 << 14) && port->identify[69] & (1 << 5))
1565 port->dd->trim_supp = true; 1569 port->dd->trim_supp = true;
1566 else 1570 else
1571#endif
1567 port->dd->trim_supp = false; 1572 port->dd->trim_supp = false;
1568 1573
1569 /* Set the identify buffer as valid. */ 1574 /* Set the identify buffer as valid. */
@@ -2557,7 +2562,7 @@ static int mtip_hw_ioctl(struct driver_data *dd, unsigned int cmd,
2557 */ 2562 */
2558static void mtip_hw_submit_io(struct driver_data *dd, sector_t sector, 2563static void mtip_hw_submit_io(struct driver_data *dd, sector_t sector,
2559 int nsect, int nents, int tag, void *callback, 2564 int nsect, int nents, int tag, void *callback,
2560 void *data, int dir) 2565 void *data, int dir, int unaligned)
2561{ 2566{
2562 struct host_to_dev_fis *fis; 2567 struct host_to_dev_fis *fis;
2563 struct mtip_port *port = dd->port; 2568 struct mtip_port *port = dd->port;
@@ -2570,6 +2575,7 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t sector,
2570 2575
2571 command->scatter_ents = nents; 2576 command->scatter_ents = nents;
2572 2577
2578 command->unaligned = unaligned;
2573 /* 2579 /*
2574 * The number of retries for this command before it is 2580 * The number of retries for this command before it is
2575 * reported as a failure to the upper layers. 2581 * reported as a failure to the upper layers.
@@ -2598,6 +2604,9 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t sector,
2598 fis->res3 = 0; 2604 fis->res3 = 0;
2599 fill_command_sg(dd, command, nents); 2605 fill_command_sg(dd, command, nents);
2600 2606
2607 if (unaligned)
2608 fis->device |= 1 << 7;
2609
2601 /* Populate the command header */ 2610 /* Populate the command header */
2602 command->command_header->opts = 2611 command->command_header->opts =
2603 __force_bit2int cpu_to_le32( 2612 __force_bit2int cpu_to_le32(
@@ -2644,9 +2653,13 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t sector,
2644 * return value 2653 * return value
2645 * None 2654 * None
2646 */ 2655 */
2647static void mtip_hw_release_scatterlist(struct driver_data *dd, int tag) 2656static void mtip_hw_release_scatterlist(struct driver_data *dd, int tag,
2657 int unaligned)
2648{ 2658{
2659 struct semaphore *sem = unaligned ? &dd->port->cmd_slot_unal :
2660 &dd->port->cmd_slot;
2649 release_slot(dd->port, tag); 2661 release_slot(dd->port, tag);
2662 up(sem);
2650} 2663}
2651 2664
2652/* 2665/*
@@ -2661,22 +2674,25 @@ static void mtip_hw_release_scatterlist(struct driver_data *dd, int tag)
2661 * or NULL if no command slots are available. 2674 * or NULL if no command slots are available.
2662 */ 2675 */
2663static struct scatterlist *mtip_hw_get_scatterlist(struct driver_data *dd, 2676static struct scatterlist *mtip_hw_get_scatterlist(struct driver_data *dd,
2664 int *tag) 2677 int *tag, int unaligned)
2665{ 2678{
2679 struct semaphore *sem = unaligned ? &dd->port->cmd_slot_unal :
2680 &dd->port->cmd_slot;
2681
2666 /* 2682 /*
2667 * It is possible that, even with this semaphore, a thread 2683 * It is possible that, even with this semaphore, a thread
2668 * may think that no command slots are available. Therefore, we 2684 * may think that no command slots are available. Therefore, we
2669 * need to make an attempt to get_slot(). 2685 * need to make an attempt to get_slot().
2670 */ 2686 */
2671 down(&dd->port->cmd_slot); 2687 down(sem);
2672 *tag = get_slot(dd->port); 2688 *tag = get_slot(dd->port);
2673 2689
2674 if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag))) { 2690 if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag))) {
2675 up(&dd->port->cmd_slot); 2691 up(sem);
2676 return NULL; 2692 return NULL;
2677 } 2693 }
2678 if (unlikely(*tag < 0)) { 2694 if (unlikely(*tag < 0)) {
2679 up(&dd->port->cmd_slot); 2695 up(sem);
2680 return NULL; 2696 return NULL;
2681 } 2697 }
2682 2698
@@ -3010,6 +3026,11 @@ static inline void hba_setup(struct driver_data *dd)
3010 dd->mmio + HOST_HSORG); 3026 dd->mmio + HOST_HSORG);
3011} 3027}
3012 3028
3029static int mtip_device_unaligned_constrained(struct driver_data *dd)
3030{
3031 return (dd->pdev->device == P420M_DEVICE_ID ? 1 : 0);
3032}
3033
3013/* 3034/*
3014 * Detect the details of the product, and store anything needed 3035 * Detect the details of the product, and store anything needed
3015 * into the driver data structure. This includes product type and 3036 * into the driver data structure. This includes product type and
@@ -3232,8 +3253,15 @@ static int mtip_hw_init(struct driver_data *dd)
3232 for (i = 0; i < MTIP_MAX_SLOT_GROUPS; i++) 3253 for (i = 0; i < MTIP_MAX_SLOT_GROUPS; i++)
3233 dd->work[i].port = dd->port; 3254 dd->work[i].port = dd->port;
3234 3255
3256 /* Enable unaligned IO constraints for some devices */
3257 if (mtip_device_unaligned_constrained(dd))
3258 dd->unal_qdepth = MTIP_MAX_UNALIGNED_SLOTS;
3259 else
3260 dd->unal_qdepth = 0;
3261
3235 /* Counting semaphore to track command slot usage */ 3262 /* Counting semaphore to track command slot usage */
3236 sema_init(&dd->port->cmd_slot, num_command_slots - 1); 3263 sema_init(&dd->port->cmd_slot, num_command_slots - 1 - dd->unal_qdepth);
3264 sema_init(&dd->port->cmd_slot_unal, dd->unal_qdepth);
3237 3265
3238 /* Spinlock to prevent concurrent issue */ 3266 /* Spinlock to prevent concurrent issue */
3239 for (i = 0; i < MTIP_MAX_SLOT_GROUPS; i++) 3267 for (i = 0; i < MTIP_MAX_SLOT_GROUPS; i++)
@@ -3836,7 +3864,7 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio)
3836 struct scatterlist *sg; 3864 struct scatterlist *sg;
3837 struct bio_vec *bvec; 3865 struct bio_vec *bvec;
3838 int nents = 0; 3866 int nents = 0;
3839 int tag = 0; 3867 int tag = 0, unaligned = 0;
3840 3868
3841 if (unlikely(dd->dd_flag & MTIP_DDF_STOP_IO)) { 3869 if (unlikely(dd->dd_flag & MTIP_DDF_STOP_IO)) {
3842 if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT, 3870 if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT,
@@ -3872,7 +3900,15 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio)
3872 return; 3900 return;
3873 } 3901 }
3874 3902
3875 sg = mtip_hw_get_scatterlist(dd, &tag); 3903 if (bio_data_dir(bio) == WRITE && bio_sectors(bio) <= 64 &&
3904 dd->unal_qdepth) {
3905 if (bio->bi_sector % 8 != 0) /* Unaligned on 4k boundaries */
3906 unaligned = 1;
3907 else if (bio_sectors(bio) % 8 != 0) /* Aligned but not 4k/8k */
3908 unaligned = 1;
3909 }
3910
3911 sg = mtip_hw_get_scatterlist(dd, &tag, unaligned);
3876 if (likely(sg != NULL)) { 3912 if (likely(sg != NULL)) {
3877 blk_queue_bounce(queue, &bio); 3913 blk_queue_bounce(queue, &bio);
3878 3914
@@ -3880,7 +3916,7 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio)
3880 dev_warn(&dd->pdev->dev, 3916 dev_warn(&dd->pdev->dev,
3881 "Maximum number of SGL entries exceeded\n"); 3917 "Maximum number of SGL entries exceeded\n");
3882 bio_io_error(bio); 3918 bio_io_error(bio);
3883 mtip_hw_release_scatterlist(dd, tag); 3919 mtip_hw_release_scatterlist(dd, tag, unaligned);
3884 return; 3920 return;
3885 } 3921 }
3886 3922
@@ -3900,7 +3936,8 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio)
3900 tag, 3936 tag,
3901 bio_endio, 3937 bio_endio,
3902 bio, 3938 bio,
3903 bio_data_dir(bio)); 3939 bio_data_dir(bio),
3940 unaligned);
3904 } else 3941 } else
3905 bio_io_error(bio); 3942 bio_io_error(bio);
3906} 3943}
@@ -4156,26 +4193,24 @@ static int mtip_block_remove(struct driver_data *dd)
4156 */ 4193 */
4157static int mtip_block_shutdown(struct driver_data *dd) 4194static int mtip_block_shutdown(struct driver_data *dd)
4158{ 4195{
4159 dev_info(&dd->pdev->dev,
4160 "Shutting down %s ...\n", dd->disk->disk_name);
4161
4162 /* Delete our gendisk structure, and cleanup the blk queue. */ 4196 /* Delete our gendisk structure, and cleanup the blk queue. */
4163 if (dd->disk) { 4197 if (dd->disk) {
4164 if (dd->disk->queue) 4198 dev_info(&dd->pdev->dev,
4199 "Shutting down %s ...\n", dd->disk->disk_name);
4200
4201 if (dd->disk->queue) {
4165 del_gendisk(dd->disk); 4202 del_gendisk(dd->disk);
4166 else 4203 blk_cleanup_queue(dd->queue);
4204 } else
4167 put_disk(dd->disk); 4205 put_disk(dd->disk);
4206 dd->disk = NULL;
4207 dd->queue = NULL;
4168 } 4208 }
4169 4209
4170
4171 spin_lock(&rssd_index_lock); 4210 spin_lock(&rssd_index_lock);
4172 ida_remove(&rssd_index_ida, dd->index); 4211 ida_remove(&rssd_index_ida, dd->index);
4173 spin_unlock(&rssd_index_lock); 4212 spin_unlock(&rssd_index_lock);
4174 4213
4175 blk_cleanup_queue(dd->queue);
4176 dd->disk = NULL;
4177 dd->queue = NULL;
4178
4179 mtip_hw_shutdown(dd); 4214 mtip_hw_shutdown(dd);
4180 return 0; 4215 return 0;
4181} 4216}
diff --git a/drivers/block/mtip32xx/mtip32xx.h b/drivers/block/mtip32xx/mtip32xx.h
index 8e8334c9dd0f..3bb8a295fbe4 100644
--- a/drivers/block/mtip32xx/mtip32xx.h
+++ b/drivers/block/mtip32xx/mtip32xx.h
@@ -52,6 +52,9 @@
52#define MTIP_FTL_REBUILD_MAGIC 0xED51 52#define MTIP_FTL_REBUILD_MAGIC 0xED51
53#define MTIP_FTL_REBUILD_TIMEOUT_MS 2400000 53#define MTIP_FTL_REBUILD_TIMEOUT_MS 2400000
54 54
55/* unaligned IO handling */
56#define MTIP_MAX_UNALIGNED_SLOTS 8
57
55/* Macro to extract the tag bit number from a tag value. */ 58/* Macro to extract the tag bit number from a tag value. */
56#define MTIP_TAG_BIT(tag) (tag & 0x1F) 59#define MTIP_TAG_BIT(tag) (tag & 0x1F)
57 60
@@ -333,6 +336,8 @@ struct mtip_cmd {
333 336
334 int scatter_ents; /* Number of scatter list entries used */ 337 int scatter_ents; /* Number of scatter list entries used */
335 338
339 int unaligned; /* command is unaligned on 4k boundary */
340
336 struct scatterlist sg[MTIP_MAX_SG]; /* Scatter list entries */ 341 struct scatterlist sg[MTIP_MAX_SG]; /* Scatter list entries */
337 342
338 int retries; /* The number of retries left for this command. */ 343 int retries; /* The number of retries left for this command. */
@@ -452,6 +457,10 @@ struct mtip_port {
452 * command slots available. 457 * command slots available.
453 */ 458 */
454 struct semaphore cmd_slot; 459 struct semaphore cmd_slot;
460
461 /* Semaphore to control queue depth of unaligned IOs */
462 struct semaphore cmd_slot_unal;
463
455 /* Spinlock for working around command-issue bug. */ 464 /* Spinlock for working around command-issue bug. */
456 spinlock_t cmd_issue_lock[MTIP_MAX_SLOT_GROUPS]; 465 spinlock_t cmd_issue_lock[MTIP_MAX_SLOT_GROUPS];
457}; 466};
@@ -502,6 +511,8 @@ struct driver_data {
502 511
503 int isr_binding; 512 int isr_binding;
504 513
514 int unal_qdepth; /* qdepth of unaligned IO queue */
515
505 struct list_head online_list; /* linkage for online list */ 516 struct list_head online_list; /* linkage for online list */
506 517
507 struct list_head remove_list; /* linkage for removing list */ 518 struct list_head remove_list; /* linkage for removing list */