Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.24-rc1 701 lines 16 kB view raw
1/* 2 * Engenio/LSI RDAC DM HW handler 3 * 4 * Copyright (C) 2005 Mike Christie. All rights reserved. 5 * Copyright (C) Chandra Seetharaman, IBM Corp. 2007 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 20 * 21 */ 22#include <scsi/scsi.h> 23#include <scsi/scsi_cmnd.h> 24#include <scsi/scsi_eh.h> 25 26#define DM_MSG_PREFIX "multipath rdac" 27 28#include "dm.h" 29#include "dm-hw-handler.h" 30 31#define RDAC_DM_HWH_NAME "rdac" 32#define RDAC_DM_HWH_VER "0.4" 33 34/* 35 * LSI mode page stuff 36 * 37 * These struct definitions and the forming of the 38 * mode page were taken from the LSI RDAC 2.4 GPL'd 39 * driver, and then converted to Linux conventions. 40 */ 41#define RDAC_QUIESCENCE_TIME 20; 42/* 43 * Page Codes 44 */ 45#define RDAC_PAGE_CODE_REDUNDANT_CONTROLLER 0x2c 46 47/* 48 * Controller modes definitions 49 */ 50#define RDAC_MODE_TRANSFER_ALL_LUNS 0x01 51#define RDAC_MODE_TRANSFER_SPECIFIED_LUNS 0x02 52 53/* 54 * RDAC Options field 55 */ 56#define RDAC_FORCED_QUIESENCE 0x02 57 58#define RDAC_FAILOVER_TIMEOUT (60 * HZ) 59 60struct rdac_mode_6_hdr { 61 u8 data_len; 62 u8 medium_type; 63 u8 device_params; 64 u8 block_desc_len; 65}; 66 67struct rdac_mode_10_hdr { 68 u16 data_len; 69 u8 medium_type; 70 u8 device_params; 71 u16 reserved; 72 u16 block_desc_len; 73}; 74 75struct rdac_mode_common { 76 u8 controller_serial[16]; 77 u8 alt_controller_serial[16]; 78 u8 rdac_mode[2]; 79 u8 alt_rdac_mode[2]; 80 u8 quiescence_timeout; 81 u8 rdac_options; 82}; 83 84struct rdac_pg_legacy { 85 struct rdac_mode_6_hdr hdr; 86 u8 page_code; 87 u8 page_len; 88 struct rdac_mode_common common; 89#define MODE6_MAX_LUN 32 90 u8 lun_table[MODE6_MAX_LUN]; 91 u8 reserved2[32]; 92 u8 reserved3; 93 u8 reserved4; 94}; 95 96struct rdac_pg_expanded { 97 struct rdac_mode_10_hdr hdr; 98 u8 page_code; 99 u8 subpage_code; 100 u8 page_len[2]; 101 struct rdac_mode_common common; 102 u8 lun_table[256]; 103 u8 reserved3; 104 u8 reserved4; 105}; 106 107struct c9_inquiry { 108 u8 peripheral_info; 109 u8 page_code; /* 0xC9 */ 110 u8 reserved1; 111 u8 page_len; 112 u8 page_id[4]; /* "vace" */ 113 u8 avte_cvp; 114 u8 path_prio; 115 u8 reserved2[38]; 116}; 117 118#define SUBSYS_ID_LEN 16 119#define SLOT_ID_LEN 2 120 121struct c4_inquiry { 122 u8 peripheral_info; 123 u8 page_code; /* 0xC4 */ 124 u8 reserved1; 125 u8 page_len; 126 u8 page_id[4]; /* "subs" */ 127 u8 subsys_id[SUBSYS_ID_LEN]; 128 u8 revision[4]; 129 u8 slot_id[SLOT_ID_LEN]; 130 u8 reserved[2]; 131}; 132 133struct rdac_controller { 134 u8 subsys_id[SUBSYS_ID_LEN]; 135 u8 slot_id[SLOT_ID_LEN]; 136 int use_10_ms; 137 struct kref kref; 138 struct list_head node; /* list of all controllers */ 139 spinlock_t lock; 140 int submitted; 141 struct list_head cmd_list; /* list of commands to be submitted */ 142 union { 143 struct rdac_pg_legacy legacy; 144 struct rdac_pg_expanded expanded; 145 } mode_select; 146}; 147struct c8_inquiry { 148 u8 peripheral_info; 149 u8 page_code; /* 0xC8 */ 150 u8 reserved1; 151 u8 page_len; 152 u8 page_id[4]; /* "edid" */ 153 u8 reserved2[3]; 154 u8 vol_uniq_id_len; 155 u8 vol_uniq_id[16]; 156 u8 vol_user_label_len; 157 u8 vol_user_label[60]; 158 u8 array_uniq_id_len; 159 u8 array_unique_id[16]; 160 u8 array_user_label_len; 161 u8 array_user_label[60]; 162 u8 lun[8]; 163}; 164 165struct c2_inquiry { 166 u8 peripheral_info; 167 u8 page_code; /* 0xC2 */ 168 u8 reserved1; 169 u8 page_len; 170 u8 page_id[4]; /* "swr4" */ 171 u8 sw_version[3]; 172 u8 sw_date[3]; 173 u8 features_enabled; 174 u8 max_lun_supported; 175 u8 partitions[239]; /* Total allocation length should be 0xFF */ 176}; 177 178struct rdac_handler { 179 struct list_head entry; /* list waiting to submit MODE SELECT */ 180 unsigned timeout; 181 struct rdac_controller *ctlr; 182#define UNINITIALIZED_LUN (1 << 8) 183 unsigned lun; 184 unsigned char sense[SCSI_SENSE_BUFFERSIZE]; 185 struct dm_path *path; 186 struct work_struct work; 187#define SEND_C2_INQUIRY 1 188#define SEND_C4_INQUIRY 2 189#define SEND_C8_INQUIRY 3 190#define SEND_C9_INQUIRY 4 191#define SEND_MODE_SELECT 5 192 int cmd_to_send; 193 union { 194 struct c2_inquiry c2; 195 struct c4_inquiry c4; 196 struct c8_inquiry c8; 197 struct c9_inquiry c9; 198 } inq; 199}; 200 201static LIST_HEAD(ctlr_list); 202static DEFINE_SPINLOCK(list_lock); 203static struct workqueue_struct *rdac_wkqd; 204 205static inline int had_failures(struct request *req, int error) 206{ 207 return (error || host_byte(req->errors) != DID_OK || 208 msg_byte(req->errors) != COMMAND_COMPLETE); 209} 210 211static void rdac_resubmit_all(struct rdac_handler *h) 212{ 213 struct rdac_controller *ctlr = h->ctlr; 214 struct rdac_handler *tmp, *h1; 215 216 spin_lock(&ctlr->lock); 217 list_for_each_entry_safe(h1, tmp, &ctlr->cmd_list, entry) { 218 h1->cmd_to_send = SEND_C9_INQUIRY; 219 queue_work(rdac_wkqd, &h1->work); 220 list_del(&h1->entry); 221 } 222 ctlr->submitted = 0; 223 spin_unlock(&ctlr->lock); 224} 225 226static void mode_select_endio(struct request *req, int error) 227{ 228 struct rdac_handler *h = req->end_io_data; 229 struct scsi_sense_hdr sense_hdr; 230 int sense = 0, fail = 0; 231 232 if (had_failures(req, error)) { 233 fail = 1; 234 goto failed; 235 } 236 237 if (status_byte(req->errors) == CHECK_CONDITION) { 238 scsi_normalize_sense(req->sense, SCSI_SENSE_BUFFERSIZE, 239 &sense_hdr); 240 sense = (sense_hdr.sense_key << 16) | (sense_hdr.asc << 8) | 241 sense_hdr.ascq; 242 /* If it is retryable failure, submit the c9 inquiry again */ 243 if (sense == 0x59136 || sense == 0x68b02 || sense == 0xb8b02 || 244 sense == 0x62900) { 245 /* 0x59136 - Command lock contention 246 * 0x[6b]8b02 - Quiesense in progress or achieved 247 * 0x62900 - Power On, Reset, or Bus Device Reset 248 */ 249 h->cmd_to_send = SEND_C9_INQUIRY; 250 queue_work(rdac_wkqd, &h->work); 251 goto done; 252 } 253 if (sense) 254 DMINFO("MODE_SELECT failed on %s with sense 0x%x", 255 h->path->dev->name, sense); 256 } 257failed: 258 if (fail || sense) 259 dm_pg_init_complete(h->path, MP_FAIL_PATH); 260 else 261 dm_pg_init_complete(h->path, 0); 262 263done: 264 rdac_resubmit_all(h); 265 __blk_put_request(req->q, req); 266} 267 268static struct request *get_rdac_req(struct rdac_handler *h, 269 void *buffer, unsigned buflen, int rw) 270{ 271 struct request *rq; 272 struct request_queue *q = bdev_get_queue(h->path->dev->bdev); 273 274 rq = blk_get_request(q, rw, GFP_KERNEL); 275 276 if (!rq) { 277 DMINFO("get_rdac_req: blk_get_request failed"); 278 return NULL; 279 } 280 281 if (buflen && blk_rq_map_kern(q, rq, buffer, buflen, GFP_KERNEL)) { 282 blk_put_request(rq); 283 DMINFO("get_rdac_req: blk_rq_map_kern failed"); 284 return NULL; 285 } 286 287 memset(&rq->cmd, 0, BLK_MAX_CDB); 288 rq->sense = h->sense; 289 memset(rq->sense, 0, SCSI_SENSE_BUFFERSIZE); 290 rq->sense_len = 0; 291 292 rq->end_io_data = h; 293 rq->timeout = h->timeout; 294 rq->cmd_type = REQ_TYPE_BLOCK_PC; 295 rq->cmd_flags |= REQ_FAILFAST | REQ_NOMERGE; 296 return rq; 297} 298 299static struct request *rdac_failover_get(struct rdac_handler *h) 300{ 301 struct request *rq; 302 struct rdac_mode_common *common; 303 unsigned data_size; 304 305 if (h->ctlr->use_10_ms) { 306 struct rdac_pg_expanded *rdac_pg; 307 308 data_size = sizeof(struct rdac_pg_expanded); 309 rdac_pg = &h->ctlr->mode_select.expanded; 310 memset(rdac_pg, 0, data_size); 311 common = &rdac_pg->common; 312 rdac_pg->page_code = RDAC_PAGE_CODE_REDUNDANT_CONTROLLER + 0x40; 313 rdac_pg->subpage_code = 0x1; 314 rdac_pg->page_len[0] = 0x01; 315 rdac_pg->page_len[1] = 0x28; 316 rdac_pg->lun_table[h->lun] = 0x81; 317 } else { 318 struct rdac_pg_legacy *rdac_pg; 319 320 data_size = sizeof(struct rdac_pg_legacy); 321 rdac_pg = &h->ctlr->mode_select.legacy; 322 memset(rdac_pg, 0, data_size); 323 common = &rdac_pg->common; 324 rdac_pg->page_code = RDAC_PAGE_CODE_REDUNDANT_CONTROLLER; 325 rdac_pg->page_len = 0x68; 326 rdac_pg->lun_table[h->lun] = 0x81; 327 } 328 common->rdac_mode[1] = RDAC_MODE_TRANSFER_SPECIFIED_LUNS; 329 common->quiescence_timeout = RDAC_QUIESCENCE_TIME; 330 common->rdac_options = RDAC_FORCED_QUIESENCE; 331 332 /* get request for block layer packet command */ 333 rq = get_rdac_req(h, &h->ctlr->mode_select, data_size, WRITE); 334 if (!rq) { 335 DMERR("rdac_failover_get: no rq"); 336 return NULL; 337 } 338 339 /* Prepare the command. */ 340 if (h->ctlr->use_10_ms) { 341 rq->cmd[0] = MODE_SELECT_10; 342 rq->cmd[7] = data_size >> 8; 343 rq->cmd[8] = data_size & 0xff; 344 } else { 345 rq->cmd[0] = MODE_SELECT; 346 rq->cmd[4] = data_size; 347 } 348 rq->cmd_len = COMMAND_SIZE(rq->cmd[0]); 349 350 return rq; 351} 352 353/* Acquires h->ctlr->lock */ 354static void submit_mode_select(struct rdac_handler *h) 355{ 356 struct request *rq; 357 struct request_queue *q = bdev_get_queue(h->path->dev->bdev); 358 359 spin_lock(&h->ctlr->lock); 360 if (h->ctlr->submitted) { 361 list_add(&h->entry, &h->ctlr->cmd_list); 362 goto drop_lock; 363 } 364 365 if (!q) { 366 DMINFO("submit_mode_select: no queue"); 367 goto fail_path; 368 } 369 370 rq = rdac_failover_get(h); 371 if (!rq) { 372 DMERR("submit_mode_select: no rq"); 373 goto fail_path; 374 } 375 376 DMINFO("queueing MODE_SELECT command on %s", h->path->dev->name); 377 378 blk_execute_rq_nowait(q, NULL, rq, 1, mode_select_endio); 379 h->ctlr->submitted = 1; 380 goto drop_lock; 381fail_path: 382 dm_pg_init_complete(h->path, MP_FAIL_PATH); 383drop_lock: 384 spin_unlock(&h->ctlr->lock); 385} 386 387static void release_ctlr(struct kref *kref) 388{ 389 struct rdac_controller *ctlr; 390 ctlr = container_of(kref, struct rdac_controller, kref); 391 392 spin_lock(&list_lock); 393 list_del(&ctlr->node); 394 spin_unlock(&list_lock); 395 kfree(ctlr); 396} 397 398static struct rdac_controller *get_controller(u8 *subsys_id, u8 *slot_id) 399{ 400 struct rdac_controller *ctlr, *tmp; 401 402 spin_lock(&list_lock); 403 404 list_for_each_entry(tmp, &ctlr_list, node) { 405 if ((memcmp(tmp->subsys_id, subsys_id, SUBSYS_ID_LEN) == 0) && 406 (memcmp(tmp->slot_id, slot_id, SLOT_ID_LEN) == 0)) { 407 kref_get(&tmp->kref); 408 spin_unlock(&list_lock); 409 return tmp; 410 } 411 } 412 ctlr = kmalloc(sizeof(*ctlr), GFP_ATOMIC); 413 if (!ctlr) 414 goto done; 415 416 /* initialize fields of controller */ 417 memcpy(ctlr->subsys_id, subsys_id, SUBSYS_ID_LEN); 418 memcpy(ctlr->slot_id, slot_id, SLOT_ID_LEN); 419 kref_init(&ctlr->kref); 420 spin_lock_init(&ctlr->lock); 421 ctlr->submitted = 0; 422 ctlr->use_10_ms = -1; 423 INIT_LIST_HEAD(&ctlr->cmd_list); 424 list_add(&ctlr->node, &ctlr_list); 425done: 426 spin_unlock(&list_lock); 427 return ctlr; 428} 429 430static void c4_endio(struct request *req, int error) 431{ 432 struct rdac_handler *h = req->end_io_data; 433 struct c4_inquiry *sp; 434 435 if (had_failures(req, error)) { 436 dm_pg_init_complete(h->path, MP_FAIL_PATH); 437 goto done; 438 } 439 440 sp = &h->inq.c4; 441 442 h->ctlr = get_controller(sp->subsys_id, sp->slot_id); 443 444 if (h->ctlr) { 445 h->cmd_to_send = SEND_C9_INQUIRY; 446 queue_work(rdac_wkqd, &h->work); 447 } else 448 dm_pg_init_complete(h->path, MP_FAIL_PATH); 449done: 450 __blk_put_request(req->q, req); 451} 452 453static void c2_endio(struct request *req, int error) 454{ 455 struct rdac_handler *h = req->end_io_data; 456 struct c2_inquiry *sp; 457 458 if (had_failures(req, error)) { 459 dm_pg_init_complete(h->path, MP_FAIL_PATH); 460 goto done; 461 } 462 463 sp = &h->inq.c2; 464 465 /* If more than MODE6_MAX_LUN luns are supported, use mode select 10 */ 466 if (sp->max_lun_supported >= MODE6_MAX_LUN) 467 h->ctlr->use_10_ms = 1; 468 else 469 h->ctlr->use_10_ms = 0; 470 471 h->cmd_to_send = SEND_MODE_SELECT; 472 queue_work(rdac_wkqd, &h->work); 473done: 474 __blk_put_request(req->q, req); 475} 476 477static void c9_endio(struct request *req, int error) 478{ 479 struct rdac_handler *h = req->end_io_data; 480 struct c9_inquiry *sp; 481 482 if (had_failures(req, error)) { 483 dm_pg_init_complete(h->path, MP_FAIL_PATH); 484 goto done; 485 } 486 487 /* We need to look at the sense keys here to take clear action. 488 * For now simple logic: If the host is in AVT mode or if controller 489 * owns the lun, return dm_pg_init_complete(), otherwise submit 490 * MODE SELECT. 491 */ 492 sp = &h->inq.c9; 493 494 /* If in AVT mode, return success */ 495 if ((sp->avte_cvp >> 7) == 0x1) { 496 dm_pg_init_complete(h->path, 0); 497 goto done; 498 } 499 500 /* If the controller on this path owns the LUN, return success */ 501 if (sp->avte_cvp & 0x1) { 502 dm_pg_init_complete(h->path, 0); 503 goto done; 504 } 505 506 if (h->ctlr) { 507 if (h->ctlr->use_10_ms == -1) 508 h->cmd_to_send = SEND_C2_INQUIRY; 509 else 510 h->cmd_to_send = SEND_MODE_SELECT; 511 } else 512 h->cmd_to_send = SEND_C4_INQUIRY; 513 queue_work(rdac_wkqd, &h->work); 514done: 515 __blk_put_request(req->q, req); 516} 517 518static void c8_endio(struct request *req, int error) 519{ 520 struct rdac_handler *h = req->end_io_data; 521 struct c8_inquiry *sp; 522 523 if (had_failures(req, error)) { 524 dm_pg_init_complete(h->path, MP_FAIL_PATH); 525 goto done; 526 } 527 528 /* We need to look at the sense keys here to take clear action. 529 * For now simple logic: Get the lun from the inquiry page. 530 */ 531 sp = &h->inq.c8; 532 h->lun = sp->lun[7]; /* currently it uses only one byte */ 533 h->cmd_to_send = SEND_C9_INQUIRY; 534 queue_work(rdac_wkqd, &h->work); 535done: 536 __blk_put_request(req->q, req); 537} 538 539static void submit_inquiry(struct rdac_handler *h, int page_code, 540 unsigned int len, rq_end_io_fn endio) 541{ 542 struct request *rq; 543 struct request_queue *q = bdev_get_queue(h->path->dev->bdev); 544 545 if (!q) 546 goto fail_path; 547 548 rq = get_rdac_req(h, &h->inq, len, READ); 549 if (!rq) 550 goto fail_path; 551 552 /* Prepare the command. */ 553 rq->cmd[0] = INQUIRY; 554 rq->cmd[1] = 1; 555 rq->cmd[2] = page_code; 556 rq->cmd[4] = len; 557 rq->cmd_len = COMMAND_SIZE(INQUIRY); 558 blk_execute_rq_nowait(q, NULL, rq, 1, endio); 559 return; 560 561fail_path: 562 dm_pg_init_complete(h->path, MP_FAIL_PATH); 563} 564 565static void service_wkq(struct work_struct *work) 566{ 567 struct rdac_handler *h = container_of(work, struct rdac_handler, work); 568 569 switch (h->cmd_to_send) { 570 case SEND_C2_INQUIRY: 571 submit_inquiry(h, 0xC2, sizeof(struct c2_inquiry), c2_endio); 572 break; 573 case SEND_C4_INQUIRY: 574 submit_inquiry(h, 0xC4, sizeof(struct c4_inquiry), c4_endio); 575 break; 576 case SEND_C8_INQUIRY: 577 submit_inquiry(h, 0xC8, sizeof(struct c8_inquiry), c8_endio); 578 break; 579 case SEND_C9_INQUIRY: 580 submit_inquiry(h, 0xC9, sizeof(struct c9_inquiry), c9_endio); 581 break; 582 case SEND_MODE_SELECT: 583 submit_mode_select(h); 584 break; 585 default: 586 BUG(); 587 } 588} 589/* 590 * only support subpage2c until we confirm that this is just a matter of 591 * of updating firmware or not, and RDAC (basic AVT works already) for now 592 * but we can add these in in when we get time and testers 593 */ 594static int rdac_create(struct hw_handler *hwh, unsigned argc, char **argv) 595{ 596 struct rdac_handler *h; 597 unsigned timeout; 598 599 if (argc == 0) { 600 /* No arguments: use defaults */ 601 timeout = RDAC_FAILOVER_TIMEOUT; 602 } else if (argc != 1) { 603 DMWARN("incorrect number of arguments"); 604 return -EINVAL; 605 } else { 606 if (sscanf(argv[1], "%u", &timeout) != 1) { 607 DMWARN("invalid timeout value"); 608 return -EINVAL; 609 } 610 } 611 612 h = kzalloc(sizeof(*h), GFP_KERNEL); 613 if (!h) 614 return -ENOMEM; 615 616 hwh->context = h; 617 h->timeout = timeout; 618 h->lun = UNINITIALIZED_LUN; 619 INIT_WORK(&h->work, service_wkq); 620 DMWARN("using RDAC command with timeout %u", h->timeout); 621 622 return 0; 623} 624 625static void rdac_destroy(struct hw_handler *hwh) 626{ 627 struct rdac_handler *h = hwh->context; 628 629 if (h->ctlr) 630 kref_put(&h->ctlr->kref, release_ctlr); 631 kfree(h); 632 hwh->context = NULL; 633} 634 635static unsigned rdac_error(struct hw_handler *hwh, struct bio *bio) 636{ 637 /* Try default handler */ 638 return dm_scsi_err_handler(hwh, bio); 639} 640 641static void rdac_pg_init(struct hw_handler *hwh, unsigned bypassed, 642 struct dm_path *path) 643{ 644 struct rdac_handler *h = hwh->context; 645 646 h->path = path; 647 switch (h->lun) { 648 case UNINITIALIZED_LUN: 649 submit_inquiry(h, 0xC8, sizeof(struct c8_inquiry), c8_endio); 650 break; 651 default: 652 submit_inquiry(h, 0xC9, sizeof(struct c9_inquiry), c9_endio); 653 } 654} 655 656static struct hw_handler_type rdac_handler = { 657 .name = RDAC_DM_HWH_NAME, 658 .module = THIS_MODULE, 659 .create = rdac_create, 660 .destroy = rdac_destroy, 661 .pg_init = rdac_pg_init, 662 .error = rdac_error, 663}; 664 665static int __init rdac_init(void) 666{ 667 int r; 668 669 rdac_wkqd = create_singlethread_workqueue("rdac_wkqd"); 670 if (!rdac_wkqd) { 671 DMERR("Failed to create workqueue rdac_wkqd."); 672 return -ENOMEM; 673 } 674 675 r = dm_register_hw_handler(&rdac_handler); 676 if (r < 0) { 677 DMERR("%s: register failed %d", RDAC_DM_HWH_NAME, r); 678 destroy_workqueue(rdac_wkqd); 679 return r; 680 } 681 682 DMINFO("%s: version %s loaded", RDAC_DM_HWH_NAME, RDAC_DM_HWH_VER); 683 return 0; 684} 685 686static void __exit rdac_exit(void) 687{ 688 int r = dm_unregister_hw_handler(&rdac_handler); 689 690 destroy_workqueue(rdac_wkqd); 691 if (r < 0) 692 DMERR("%s: unregister failed %d", RDAC_DM_HWH_NAME, r); 693} 694 695module_init(rdac_init); 696module_exit(rdac_exit); 697 698MODULE_DESCRIPTION("DM Multipath LSI/Engenio RDAC support"); 699MODULE_AUTHOR("Mike Christie, Chandra Seetharaman"); 700MODULE_LICENSE("GPL"); 701MODULE_VERSION(RDAC_DM_HWH_VER);