aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/mtip32xx
diff options
context:
space:
mode:
authorAsai Thambi S P <asamymuthupa@micron.com>2012-01-04 16:01:32 -0500
committerJens Axboe <axboe@kernel.dk>2012-01-04 16:01:32 -0500
commit62ee8c13e26cffe6483630f59932c3e936dfb586 (patch)
tree7f92cc63e2413b19466255133f1198319dd4ae4f /drivers/block/mtip32xx
parent3e54a3d1b83220d748f1a27c8999634be7a83949 (diff)
mtip32xx: do rebuild monitoring asynchronously
Earlier, rebuild monitoring was done in the context of probe. Now the service thread takes the responsibility of rebuild monitoring, and probe returns good status. Signed-off-by: Asai Thambi S P <asamymuthupa@micron.com> Signed-off-by: Sam Bradshaw <sbradshaw@micron.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'drivers/block/mtip32xx')
-rw-r--r--drivers/block/mtip32xx/mtip32xx.c104
-rw-r--r--drivers/block/mtip32xx/mtip32xx.h1
2 files changed, 65 insertions, 40 deletions
diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c
index 9bc10e31a143..b74eab70c3d0 100644
--- a/drivers/block/mtip32xx/mtip32xx.c
+++ b/drivers/block/mtip32xx/mtip32xx.c
@@ -87,6 +87,8 @@ static int mtip_major;
87static DEFINE_SPINLOCK(rssd_index_lock); 87static DEFINE_SPINLOCK(rssd_index_lock);
88static DEFINE_IDA(rssd_index_ida); 88static DEFINE_IDA(rssd_index_ida);
89 89
90static int mtip_block_initialize(struct driver_data *dd);
91
90#ifdef CONFIG_COMPAT 92#ifdef CONFIG_COMPAT
91struct mtip_compat_ide_task_request_s { 93struct mtip_compat_ide_task_request_s {
92 __u8 io_ports[8]; 94 __u8 io_ports[8];
@@ -1031,7 +1033,8 @@ static int mtip_quiesce_io(struct mtip_port *port, unsigned long timeout)
1031 1033
1032 to = jiffies + msecs_to_jiffies(timeout); 1034 to = jiffies + msecs_to_jiffies(timeout);
1033 do { 1035 do {
1034 if (test_bit(MTIP_FLAG_SVC_THD_ACTIVE_BIT, &port->flags)) { 1036 if (test_bit(MTIP_FLAG_SVC_THD_ACTIVE_BIT, &port->flags) &&
1037 test_bit(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags)) {
1035 msleep(20); 1038 msleep(20);
1036 continue; /* svc thd is actively issuing commands */ 1039 continue; /* svc thd is actively issuing commands */
1037 } 1040 }
@@ -2410,6 +2413,7 @@ static int mtip_ftl_rebuild_poll(struct driver_data *dd)
2410 "FTL rebuild complete (%d secs).\n", 2413 "FTL rebuild complete (%d secs).\n",
2411 jiffies_to_msecs(jiffies - start) / 1000); 2414 jiffies_to_msecs(jiffies - start) / 1000);
2412 dd->ftlrebuildflag = 0; 2415 dd->ftlrebuildflag = 0;
2416 mtip_block_initialize(dd);
2413 break; 2417 break;
2414 } 2418 }
2415 ssleep(10); 2419 ssleep(10);
@@ -2454,8 +2458,8 @@ static int mtip_service_thread(void *data)
2454 if (kthread_should_stop()) 2458 if (kthread_should_stop())
2455 break; 2459 break;
2456 2460
2461 set_bit(MTIP_FLAG_SVC_THD_ACTIVE_BIT, &port->flags);
2457 if (test_bit(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags)) { 2462 if (test_bit(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags)) {
2458 set_bit(MTIP_FLAG_SVC_THD_ACTIVE_BIT, &port->flags);
2459 slot = 1; 2463 slot = 1;
2460 /* used to restrict the loop to one iteration */ 2464 /* used to restrict the loop to one iteration */
2461 slot_start = num_cmd_slots; 2465 slot_start = num_cmd_slots;
@@ -2488,8 +2492,14 @@ static int mtip_service_thread(void *data)
2488 } 2492 }
2489 2493
2490 clear_bit(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags); 2494 clear_bit(MTIP_FLAG_ISSUE_CMDS_BIT, &port->flags);
2491 clear_bit(MTIP_FLAG_SVC_THD_ACTIVE_BIT, &port->flags); 2495 } else if (test_bit(MTIP_FLAG_REBUILD_BIT, &port->flags)) {
2496 mtip_ftl_rebuild_poll(dd);
2497 clear_bit(MTIP_FLAG_REBUILD_BIT, &port->flags);
2492 } 2498 }
2499 clear_bit(MTIP_FLAG_SVC_THD_ACTIVE_BIT, &port->flags);
2500
2501 if (test_bit(MTIP_FLAG_SVC_THD_SHOULD_STOP_BIT, &port->flags))
2502 break;
2493 } 2503 }
2494 return 0; 2504 return 0;
2495} 2505}
@@ -2658,12 +2668,13 @@ static int mtip_hw_init(struct driver_data *dd)
2658 rv = -EFAULT; 2668 rv = -EFAULT;
2659 goto out3; 2669 goto out3;
2660 } 2670 }
2661 mtip_dump_identify(dd->port);
2662 2671
2663 if (*(dd->port->identify + MTIP_FTL_REBUILD_OFFSET) == 2672 if (*(dd->port->identify + MTIP_FTL_REBUILD_OFFSET) ==
2664 MTIP_FTL_REBUILD_MAGIC) { 2673 MTIP_FTL_REBUILD_MAGIC) {
2665 return mtip_ftl_rebuild_poll(dd); 2674 set_bit(MTIP_FLAG_REBUILD_BIT, &dd->port->flags);
2675 return MTIP_FTL_REBUILD_MAGIC;
2666 } 2676 }
2677 mtip_dump_identify(dd->port);
2667 return rv; 2678 return rv;
2668 2679
2669out3: 2680out3:
@@ -3095,40 +3106,24 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio)
3095 */ 3106 */
3096static int mtip_block_initialize(struct driver_data *dd) 3107static int mtip_block_initialize(struct driver_data *dd)
3097{ 3108{
3098 int rv = 0; 3109 int rv = 0, wait_for_rebuild = 0;
3099 sector_t capacity; 3110 sector_t capacity;
3100 unsigned int index = 0; 3111 unsigned int index = 0;
3101 struct kobject *kobj; 3112 struct kobject *kobj;
3102 unsigned char thd_name[16]; 3113 unsigned char thd_name[16];
3103 3114
3115 if (dd->disk)
3116 goto skip_create_disk; /* hw init done, before rebuild */
3117
3104 /* Initialize the protocol layer. */ 3118 /* Initialize the protocol layer. */
3105 rv = mtip_hw_init(dd); 3119 wait_for_rebuild = mtip_hw_init(dd);
3106 if (rv < 0) { 3120 if (wait_for_rebuild < 0) {
3107 dev_err(&dd->pdev->dev, 3121 dev_err(&dd->pdev->dev,
3108 "Protocol layer initialization failed\n"); 3122 "Protocol layer initialization failed\n");
3109 rv = -EINVAL; 3123 rv = -EINVAL;
3110 goto protocol_init_error; 3124 goto protocol_init_error;
3111 } 3125 }
3112 3126
3113 /* Allocate the request queue. */
3114 dd->queue = blk_alloc_queue(GFP_KERNEL);
3115 if (dd->queue == NULL) {
3116 dev_err(&dd->pdev->dev,
3117 "Unable to allocate request queue\n");
3118 rv = -ENOMEM;
3119 goto block_queue_alloc_init_error;
3120 }
3121
3122 /* Attach our request function to the request queue. */
3123 blk_queue_make_request(dd->queue, mtip_make_request);
3124
3125 /* Set device limits. */
3126 set_bit(QUEUE_FLAG_NONROT, &dd->queue->queue_flags);
3127 blk_queue_max_segments(dd->queue, MTIP_MAX_SG);
3128 blk_queue_physical_block_size(dd->queue, 4096);
3129 blk_queue_io_min(dd->queue, 4096);
3130 blk_queue_flush(dd->queue, 0);
3131
3132 dd->disk = alloc_disk(MTIP_MAX_MINORS); 3127 dd->disk = alloc_disk(MTIP_MAX_MINORS);
3133 if (dd->disk == NULL) { 3128 if (dd->disk == NULL) {
3134 dev_err(&dd->pdev->dev, 3129 dev_err(&dd->pdev->dev,
@@ -3161,11 +3156,39 @@ static int mtip_block_initialize(struct driver_data *dd)
3161 dd->disk->major = dd->major; 3156 dd->disk->major = dd->major;
3162 dd->disk->first_minor = dd->instance * MTIP_MAX_MINORS; 3157 dd->disk->first_minor = dd->instance * MTIP_MAX_MINORS;
3163 dd->disk->fops = &mtip_block_ops; 3158 dd->disk->fops = &mtip_block_ops;
3164 dd->disk->queue = dd->queue;
3165 dd->disk->private_data = dd; 3159 dd->disk->private_data = dd;
3166 dd->queue->queuedata = dd;
3167 dd->index = index; 3160 dd->index = index;
3168 3161
3162 /*
3163 * if rebuild pending, start the service thread, and delay the block
3164 * queue creation and add_disk()
3165 */
3166 if (wait_for_rebuild == MTIP_FTL_REBUILD_MAGIC)
3167 goto start_service_thread;
3168
3169skip_create_disk:
3170 /* Allocate the request queue. */
3171 dd->queue = blk_alloc_queue(GFP_KERNEL);
3172 if (dd->queue == NULL) {
3173 dev_err(&dd->pdev->dev,
3174 "Unable to allocate request queue\n");
3175 rv = -ENOMEM;
3176 goto block_queue_alloc_init_error;
3177 }
3178
3179 /* Attach our request function to the request queue. */
3180 blk_queue_make_request(dd->queue, mtip_make_request);
3181
3182 dd->disk->queue = dd->queue;
3183 dd->queue->queuedata = dd;
3184
3185 /* Set device limits. */
3186 set_bit(QUEUE_FLAG_NONROT, &dd->queue->queue_flags);
3187 blk_queue_max_segments(dd->queue, MTIP_MAX_SG);
3188 blk_queue_physical_block_size(dd->queue, 4096);
3189 blk_queue_io_min(dd->queue, 4096);
3190 blk_queue_flush(dd->queue, 0);
3191
3169 /* Set the capacity of the device in 512 byte sectors. */ 3192 /* Set the capacity of the device in 512 byte sectors. */
3170 if (!(mtip_hw_get_capacity(dd, &capacity))) { 3193 if (!(mtip_hw_get_capacity(dd, &capacity))) {
3171 dev_warn(&dd->pdev->dev, 3194 dev_warn(&dd->pdev->dev,
@@ -3188,6 +3211,10 @@ static int mtip_block_initialize(struct driver_data *dd)
3188 kobject_put(kobj); 3211 kobject_put(kobj);
3189 } 3212 }
3190 3213
3214 if (dd->mtip_svc_handler)
3215 return rv; /* service thread created for handling rebuild */
3216
3217start_service_thread:
3191 sprintf(thd_name, "mtip_svc_thd_%02d", index); 3218 sprintf(thd_name, "mtip_svc_thd_%02d", index);
3192 3219
3193 dd->mtip_svc_handler = kthread_run(mtip_service_thread, 3220 dd->mtip_svc_handler = kthread_run(mtip_service_thread,
@@ -3197,18 +3224,19 @@ static int mtip_block_initialize(struct driver_data *dd)
3197 printk(KERN_ERR "mtip32xx: service thread failed to start\n"); 3224 printk(KERN_ERR "mtip32xx: service thread failed to start\n");
3198 dd->mtip_svc_handler = NULL; 3225 dd->mtip_svc_handler = NULL;
3199 rv = -EFAULT; 3226 rv = -EFAULT;
3200 goto read_capacity_error; 3227 goto kthread_run_error;
3201 } 3228 }
3202 3229
3203 return rv; 3230 return rv;
3204 3231
3205read_capacity_error: 3232kthread_run_error:
3206 /* 3233 /* Delete our gendisk. This also removes the device from /dev */
3207 * Delete our gendisk structure. This also removes the device
3208 * from /dev
3209 */
3210 del_gendisk(dd->disk); 3234 del_gendisk(dd->disk);
3211 3235
3236read_capacity_error:
3237 blk_cleanup_queue(dd->queue);
3238
3239block_queue_alloc_init_error:
3212disk_index_error: 3240disk_index_error:
3213 spin_lock(&rssd_index_lock); 3241 spin_lock(&rssd_index_lock);
3214 ida_remove(&rssd_index_ida, index); 3242 ida_remove(&rssd_index_ida, index);
@@ -3218,11 +3246,7 @@ ida_get_error:
3218 put_disk(dd->disk); 3246 put_disk(dd->disk);
3219 3247
3220alloc_disk_error: 3248alloc_disk_error:
3221 blk_cleanup_queue(dd->queue); 3249 mtip_hw_exit(dd); /* De-initialize the protocol layer. */
3222
3223block_queue_alloc_init_error:
3224 /* De-initialize the protocol layer. */
3225 mtip_hw_exit(dd);
3226 3250
3227protocol_init_error: 3251protocol_init_error:
3228 return rv; 3252 return rv;
diff --git a/drivers/block/mtip32xx/mtip32xx.h b/drivers/block/mtip32xx/mtip32xx.h
index 933192abe178..723d7c4946dc 100644
--- a/drivers/block/mtip32xx/mtip32xx.h
+++ b/drivers/block/mtip32xx/mtip32xx.h
@@ -121,6 +121,7 @@
121#define MTIP_FLAG_EH_ACTIVE_BIT 1 121#define MTIP_FLAG_EH_ACTIVE_BIT 1
122#define MTIP_FLAG_SVC_THD_ACTIVE_BIT 2 122#define MTIP_FLAG_SVC_THD_ACTIVE_BIT 2
123#define MTIP_FLAG_ISSUE_CMDS_BIT 4 123#define MTIP_FLAG_ISSUE_CMDS_BIT 4
124#define MTIP_FLAG_REBUILD_BIT 5
124#define MTIP_FLAG_SVC_THD_SHOULD_STOP_BIT 8 125#define MTIP_FLAG_SVC_THD_SHOULD_STOP_BIT 8
125 126
126/* Register Frame Information Structure (FIS), host to device. */ 127/* Register Frame Information Structure (FIS), host to device. */