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.35 2135 lines 60 kB view raw
1/* 2 * iSCSI transport class definitions 3 * 4 * Copyright (C) IBM Corporation, 2004 5 * Copyright (C) Mike Christie, 2004 - 2005 6 * Copyright (C) Dmitry Yusupov, 2004 - 2005 7 * Copyright (C) Alex Aizman, 2004 - 2005 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 22 */ 23#include <linux/module.h> 24#include <linux/mutex.h> 25#include <linux/slab.h> 26#include <net/tcp.h> 27#include <scsi/scsi.h> 28#include <scsi/scsi_host.h> 29#include <scsi/scsi_device.h> 30#include <scsi/scsi_transport.h> 31#include <scsi/scsi_transport_iscsi.h> 32#include <scsi/iscsi_if.h> 33 34#define ISCSI_SESSION_ATTRS 22 35#define ISCSI_CONN_ATTRS 13 36#define ISCSI_HOST_ATTRS 4 37 38#define ISCSI_TRANSPORT_VERSION "2.0-870" 39 40static int dbg_session; 41module_param_named(debug_session, dbg_session, int, 42 S_IRUGO | S_IWUSR); 43MODULE_PARM_DESC(debug_session, 44 "Turn on debugging for sessions in scsi_transport_iscsi " 45 "module. Set to 1 to turn on, and zero to turn off. Default " 46 "is off."); 47 48static int dbg_conn; 49module_param_named(debug_conn, dbg_conn, int, 50 S_IRUGO | S_IWUSR); 51MODULE_PARM_DESC(debug_conn, 52 "Turn on debugging for connections in scsi_transport_iscsi " 53 "module. Set to 1 to turn on, and zero to turn off. Default " 54 "is off."); 55 56#define ISCSI_DBG_TRANS_SESSION(_session, dbg_fmt, arg...) \ 57 do { \ 58 if (dbg_session) \ 59 iscsi_cls_session_printk(KERN_INFO, _session, \ 60 "%s: " dbg_fmt, \ 61 __func__, ##arg); \ 62 } while (0); 63 64#define ISCSI_DBG_TRANS_CONN(_conn, dbg_fmt, arg...) \ 65 do { \ 66 if (dbg_conn) \ 67 iscsi_cls_conn_printk(KERN_INFO, _conn, \ 68 "%s: " dbg_fmt, \ 69 __func__, ##arg); \ 70 } while (0); 71 72struct iscsi_internal { 73 struct scsi_transport_template t; 74 struct iscsi_transport *iscsi_transport; 75 struct list_head list; 76 struct device dev; 77 78 struct device_attribute *host_attrs[ISCSI_HOST_ATTRS + 1]; 79 struct transport_container conn_cont; 80 struct device_attribute *conn_attrs[ISCSI_CONN_ATTRS + 1]; 81 struct transport_container session_cont; 82 struct device_attribute *session_attrs[ISCSI_SESSION_ATTRS + 1]; 83}; 84 85static atomic_t iscsi_session_nr; /* sysfs session id for next new session */ 86static struct workqueue_struct *iscsi_eh_timer_workq; 87 88/* 89 * list of registered transports and lock that must 90 * be held while accessing list. The iscsi_transport_lock must 91 * be acquired after the rx_queue_mutex. 92 */ 93static LIST_HEAD(iscsi_transports); 94static DEFINE_SPINLOCK(iscsi_transport_lock); 95 96#define to_iscsi_internal(tmpl) \ 97 container_of(tmpl, struct iscsi_internal, t) 98 99#define dev_to_iscsi_internal(_dev) \ 100 container_of(_dev, struct iscsi_internal, dev) 101 102static void iscsi_transport_release(struct device *dev) 103{ 104 struct iscsi_internal *priv = dev_to_iscsi_internal(dev); 105 kfree(priv); 106} 107 108/* 109 * iscsi_transport_class represents the iscsi_transports that are 110 * registered. 111 */ 112static struct class iscsi_transport_class = { 113 .name = "iscsi_transport", 114 .dev_release = iscsi_transport_release, 115}; 116 117static ssize_t 118show_transport_handle(struct device *dev, struct device_attribute *attr, 119 char *buf) 120{ 121 struct iscsi_internal *priv = dev_to_iscsi_internal(dev); 122 return sprintf(buf, "%llu\n", (unsigned long long)iscsi_handle(priv->iscsi_transport)); 123} 124static DEVICE_ATTR(handle, S_IRUGO, show_transport_handle, NULL); 125 126#define show_transport_attr(name, format) \ 127static ssize_t \ 128show_transport_##name(struct device *dev, \ 129 struct device_attribute *attr,char *buf) \ 130{ \ 131 struct iscsi_internal *priv = dev_to_iscsi_internal(dev); \ 132 return sprintf(buf, format"\n", priv->iscsi_transport->name); \ 133} \ 134static DEVICE_ATTR(name, S_IRUGO, show_transport_##name, NULL); 135 136show_transport_attr(caps, "0x%x"); 137 138static struct attribute *iscsi_transport_attrs[] = { 139 &dev_attr_handle.attr, 140 &dev_attr_caps.attr, 141 NULL, 142}; 143 144static struct attribute_group iscsi_transport_group = { 145 .attrs = iscsi_transport_attrs, 146}; 147 148/* 149 * iSCSI endpoint attrs 150 */ 151#define iscsi_dev_to_endpoint(_dev) \ 152 container_of(_dev, struct iscsi_endpoint, dev) 153 154#define ISCSI_ATTR(_prefix,_name,_mode,_show,_store) \ 155struct device_attribute dev_attr_##_prefix##_##_name = \ 156 __ATTR(_name,_mode,_show,_store) 157 158static void iscsi_endpoint_release(struct device *dev) 159{ 160 struct iscsi_endpoint *ep = iscsi_dev_to_endpoint(dev); 161 kfree(ep); 162} 163 164static struct class iscsi_endpoint_class = { 165 .name = "iscsi_endpoint", 166 .dev_release = iscsi_endpoint_release, 167}; 168 169static ssize_t 170show_ep_handle(struct device *dev, struct device_attribute *attr, char *buf) 171{ 172 struct iscsi_endpoint *ep = iscsi_dev_to_endpoint(dev); 173 return sprintf(buf, "%llu\n", (unsigned long long) ep->id); 174} 175static ISCSI_ATTR(ep, handle, S_IRUGO, show_ep_handle, NULL); 176 177static struct attribute *iscsi_endpoint_attrs[] = { 178 &dev_attr_ep_handle.attr, 179 NULL, 180}; 181 182static struct attribute_group iscsi_endpoint_group = { 183 .attrs = iscsi_endpoint_attrs, 184}; 185 186#define ISCSI_MAX_EPID -1 187 188static int iscsi_match_epid(struct device *dev, void *data) 189{ 190 struct iscsi_endpoint *ep = iscsi_dev_to_endpoint(dev); 191 uint64_t *epid = (uint64_t *) data; 192 193 return *epid == ep->id; 194} 195 196struct iscsi_endpoint * 197iscsi_create_endpoint(int dd_size) 198{ 199 struct device *dev; 200 struct iscsi_endpoint *ep; 201 uint64_t id; 202 int err; 203 204 for (id = 1; id < ISCSI_MAX_EPID; id++) { 205 dev = class_find_device(&iscsi_endpoint_class, NULL, &id, 206 iscsi_match_epid); 207 if (!dev) 208 break; 209 } 210 if (id == ISCSI_MAX_EPID) { 211 printk(KERN_ERR "Too many connections. Max supported %u\n", 212 ISCSI_MAX_EPID - 1); 213 return NULL; 214 } 215 216 ep = kzalloc(sizeof(*ep) + dd_size, GFP_KERNEL); 217 if (!ep) 218 return NULL; 219 220 ep->id = id; 221 ep->dev.class = &iscsi_endpoint_class; 222 dev_set_name(&ep->dev, "ep-%llu", (unsigned long long) id); 223 err = device_register(&ep->dev); 224 if (err) 225 goto free_ep; 226 227 err = sysfs_create_group(&ep->dev.kobj, &iscsi_endpoint_group); 228 if (err) 229 goto unregister_dev; 230 231 if (dd_size) 232 ep->dd_data = &ep[1]; 233 return ep; 234 235unregister_dev: 236 device_unregister(&ep->dev); 237 return NULL; 238 239free_ep: 240 kfree(ep); 241 return NULL; 242} 243EXPORT_SYMBOL_GPL(iscsi_create_endpoint); 244 245void iscsi_destroy_endpoint(struct iscsi_endpoint *ep) 246{ 247 sysfs_remove_group(&ep->dev.kobj, &iscsi_endpoint_group); 248 device_unregister(&ep->dev); 249} 250EXPORT_SYMBOL_GPL(iscsi_destroy_endpoint); 251 252struct iscsi_endpoint *iscsi_lookup_endpoint(u64 handle) 253{ 254 struct iscsi_endpoint *ep; 255 struct device *dev; 256 257 dev = class_find_device(&iscsi_endpoint_class, NULL, &handle, 258 iscsi_match_epid); 259 if (!dev) 260 return NULL; 261 262 ep = iscsi_dev_to_endpoint(dev); 263 /* 264 * we can drop this now because the interface will prevent 265 * removals and lookups from racing. 266 */ 267 put_device(dev); 268 return ep; 269} 270EXPORT_SYMBOL_GPL(iscsi_lookup_endpoint); 271 272static int iscsi_setup_host(struct transport_container *tc, struct device *dev, 273 struct device *cdev) 274{ 275 struct Scsi_Host *shost = dev_to_shost(dev); 276 struct iscsi_cls_host *ihost = shost->shost_data; 277 278 memset(ihost, 0, sizeof(*ihost)); 279 atomic_set(&ihost->nr_scans, 0); 280 mutex_init(&ihost->mutex); 281 return 0; 282} 283 284static DECLARE_TRANSPORT_CLASS(iscsi_host_class, 285 "iscsi_host", 286 iscsi_setup_host, 287 NULL, 288 NULL); 289 290static DECLARE_TRANSPORT_CLASS(iscsi_session_class, 291 "iscsi_session", 292 NULL, 293 NULL, 294 NULL); 295 296static DECLARE_TRANSPORT_CLASS(iscsi_connection_class, 297 "iscsi_connection", 298 NULL, 299 NULL, 300 NULL); 301 302static struct sock *nls; 303static DEFINE_MUTEX(rx_queue_mutex); 304 305static LIST_HEAD(sesslist); 306static DEFINE_SPINLOCK(sesslock); 307static LIST_HEAD(connlist); 308static DEFINE_SPINLOCK(connlock); 309 310static uint32_t iscsi_conn_get_sid(struct iscsi_cls_conn *conn) 311{ 312 struct iscsi_cls_session *sess = iscsi_dev_to_session(conn->dev.parent); 313 return sess->sid; 314} 315 316/* 317 * Returns the matching session to a given sid 318 */ 319static struct iscsi_cls_session *iscsi_session_lookup(uint32_t sid) 320{ 321 unsigned long flags; 322 struct iscsi_cls_session *sess; 323 324 spin_lock_irqsave(&sesslock, flags); 325 list_for_each_entry(sess, &sesslist, sess_list) { 326 if (sess->sid == sid) { 327 spin_unlock_irqrestore(&sesslock, flags); 328 return sess; 329 } 330 } 331 spin_unlock_irqrestore(&sesslock, flags); 332 return NULL; 333} 334 335/* 336 * Returns the matching connection to a given sid / cid tuple 337 */ 338static struct iscsi_cls_conn *iscsi_conn_lookup(uint32_t sid, uint32_t cid) 339{ 340 unsigned long flags; 341 struct iscsi_cls_conn *conn; 342 343 spin_lock_irqsave(&connlock, flags); 344 list_for_each_entry(conn, &connlist, conn_list) { 345 if ((conn->cid == cid) && (iscsi_conn_get_sid(conn) == sid)) { 346 spin_unlock_irqrestore(&connlock, flags); 347 return conn; 348 } 349 } 350 spin_unlock_irqrestore(&connlock, flags); 351 return NULL; 352} 353 354/* 355 * The following functions can be used by LLDs that allocate 356 * their own scsi_hosts or by software iscsi LLDs 357 */ 358static struct { 359 int value; 360 char *name; 361} iscsi_session_state_names[] = { 362 { ISCSI_SESSION_LOGGED_IN, "LOGGED_IN" }, 363 { ISCSI_SESSION_FAILED, "FAILED" }, 364 { ISCSI_SESSION_FREE, "FREE" }, 365}; 366 367static const char *iscsi_session_state_name(int state) 368{ 369 int i; 370 char *name = NULL; 371 372 for (i = 0; i < ARRAY_SIZE(iscsi_session_state_names); i++) { 373 if (iscsi_session_state_names[i].value == state) { 374 name = iscsi_session_state_names[i].name; 375 break; 376 } 377 } 378 return name; 379} 380 381int iscsi_session_chkready(struct iscsi_cls_session *session) 382{ 383 unsigned long flags; 384 int err; 385 386 spin_lock_irqsave(&session->lock, flags); 387 switch (session->state) { 388 case ISCSI_SESSION_LOGGED_IN: 389 err = 0; 390 break; 391 case ISCSI_SESSION_FAILED: 392 err = DID_IMM_RETRY << 16; 393 break; 394 case ISCSI_SESSION_FREE: 395 err = DID_TRANSPORT_FAILFAST << 16; 396 break; 397 default: 398 err = DID_NO_CONNECT << 16; 399 break; 400 } 401 spin_unlock_irqrestore(&session->lock, flags); 402 return err; 403} 404EXPORT_SYMBOL_GPL(iscsi_session_chkready); 405 406static void iscsi_session_release(struct device *dev) 407{ 408 struct iscsi_cls_session *session = iscsi_dev_to_session(dev); 409 struct Scsi_Host *shost; 410 411 shost = iscsi_session_to_shost(session); 412 scsi_host_put(shost); 413 ISCSI_DBG_TRANS_SESSION(session, "Completing session release\n"); 414 kfree(session); 415} 416 417static int iscsi_is_session_dev(const struct device *dev) 418{ 419 return dev->release == iscsi_session_release; 420} 421 422static int iscsi_iter_session_fn(struct device *dev, void *data) 423{ 424 void (* fn) (struct iscsi_cls_session *) = data; 425 426 if (!iscsi_is_session_dev(dev)) 427 return 0; 428 fn(iscsi_dev_to_session(dev)); 429 return 0; 430} 431 432void iscsi_host_for_each_session(struct Scsi_Host *shost, 433 void (*fn)(struct iscsi_cls_session *)) 434{ 435 device_for_each_child(&shost->shost_gendev, fn, 436 iscsi_iter_session_fn); 437} 438EXPORT_SYMBOL_GPL(iscsi_host_for_each_session); 439 440/** 441 * iscsi_scan_finished - helper to report when running scans are done 442 * @shost: scsi host 443 * @time: scan run time 444 * 445 * This function can be used by drives like qla4xxx to report to the scsi 446 * layer when the scans it kicked off at module load time are done. 447 */ 448int iscsi_scan_finished(struct Scsi_Host *shost, unsigned long time) 449{ 450 struct iscsi_cls_host *ihost = shost->shost_data; 451 /* 452 * qla4xxx will have kicked off some session unblocks before calling 453 * scsi_scan_host, so just wait for them to complete. 454 */ 455 return !atomic_read(&ihost->nr_scans); 456} 457EXPORT_SYMBOL_GPL(iscsi_scan_finished); 458 459struct iscsi_scan_data { 460 unsigned int channel; 461 unsigned int id; 462 unsigned int lun; 463}; 464 465static int iscsi_user_scan_session(struct device *dev, void *data) 466{ 467 struct iscsi_scan_data *scan_data = data; 468 struct iscsi_cls_session *session; 469 struct Scsi_Host *shost; 470 struct iscsi_cls_host *ihost; 471 unsigned long flags; 472 unsigned int id; 473 474 if (!iscsi_is_session_dev(dev)) 475 return 0; 476 477 session = iscsi_dev_to_session(dev); 478 479 ISCSI_DBG_TRANS_SESSION(session, "Scanning session\n"); 480 481 shost = iscsi_session_to_shost(session); 482 ihost = shost->shost_data; 483 484 mutex_lock(&ihost->mutex); 485 spin_lock_irqsave(&session->lock, flags); 486 if (session->state != ISCSI_SESSION_LOGGED_IN) { 487 spin_unlock_irqrestore(&session->lock, flags); 488 goto user_scan_exit; 489 } 490 id = session->target_id; 491 spin_unlock_irqrestore(&session->lock, flags); 492 493 if (id != ISCSI_MAX_TARGET) { 494 if ((scan_data->channel == SCAN_WILD_CARD || 495 scan_data->channel == 0) && 496 (scan_data->id == SCAN_WILD_CARD || 497 scan_data->id == id)) 498 scsi_scan_target(&session->dev, 0, id, 499 scan_data->lun, 1); 500 } 501 502user_scan_exit: 503 mutex_unlock(&ihost->mutex); 504 ISCSI_DBG_TRANS_SESSION(session, "Completed session scan\n"); 505 return 0; 506} 507 508static int iscsi_user_scan(struct Scsi_Host *shost, uint channel, 509 uint id, uint lun) 510{ 511 struct iscsi_scan_data scan_data; 512 513 scan_data.channel = channel; 514 scan_data.id = id; 515 scan_data.lun = lun; 516 517 return device_for_each_child(&shost->shost_gendev, &scan_data, 518 iscsi_user_scan_session); 519} 520 521static void iscsi_scan_session(struct work_struct *work) 522{ 523 struct iscsi_cls_session *session = 524 container_of(work, struct iscsi_cls_session, scan_work); 525 struct Scsi_Host *shost = iscsi_session_to_shost(session); 526 struct iscsi_cls_host *ihost = shost->shost_data; 527 struct iscsi_scan_data scan_data; 528 529 scan_data.channel = 0; 530 scan_data.id = SCAN_WILD_CARD; 531 scan_data.lun = SCAN_WILD_CARD; 532 533 iscsi_user_scan_session(&session->dev, &scan_data); 534 atomic_dec(&ihost->nr_scans); 535} 536 537static void session_recovery_timedout(struct work_struct *work) 538{ 539 struct iscsi_cls_session *session = 540 container_of(work, struct iscsi_cls_session, 541 recovery_work.work); 542 unsigned long flags; 543 544 iscsi_cls_session_printk(KERN_INFO, session, 545 "session recovery timed out after %d secs\n", 546 session->recovery_tmo); 547 548 spin_lock_irqsave(&session->lock, flags); 549 switch (session->state) { 550 case ISCSI_SESSION_FAILED: 551 session->state = ISCSI_SESSION_FREE; 552 break; 553 case ISCSI_SESSION_LOGGED_IN: 554 case ISCSI_SESSION_FREE: 555 /* we raced with the unblock's flush */ 556 spin_unlock_irqrestore(&session->lock, flags); 557 return; 558 } 559 spin_unlock_irqrestore(&session->lock, flags); 560 561 if (session->transport->session_recovery_timedout) 562 session->transport->session_recovery_timedout(session); 563 564 ISCSI_DBG_TRANS_SESSION(session, "Unblocking SCSI target\n"); 565 scsi_target_unblock(&session->dev); 566 ISCSI_DBG_TRANS_SESSION(session, "Completed unblocking SCSI target\n"); 567} 568 569static void __iscsi_unblock_session(struct work_struct *work) 570{ 571 struct iscsi_cls_session *session = 572 container_of(work, struct iscsi_cls_session, 573 unblock_work); 574 struct Scsi_Host *shost = iscsi_session_to_shost(session); 575 struct iscsi_cls_host *ihost = shost->shost_data; 576 unsigned long flags; 577 578 ISCSI_DBG_TRANS_SESSION(session, "Unblocking session\n"); 579 /* 580 * The recovery and unblock work get run from the same workqueue, 581 * so try to cancel it if it was going to run after this unblock. 582 */ 583 cancel_delayed_work(&session->recovery_work); 584 spin_lock_irqsave(&session->lock, flags); 585 session->state = ISCSI_SESSION_LOGGED_IN; 586 spin_unlock_irqrestore(&session->lock, flags); 587 /* start IO */ 588 scsi_target_unblock(&session->dev); 589 /* 590 * Only do kernel scanning if the driver is properly hooked into 591 * the async scanning code (drivers like iscsi_tcp do login and 592 * scanning from userspace). 593 */ 594 if (shost->hostt->scan_finished) { 595 if (scsi_queue_work(shost, &session->scan_work)) 596 atomic_inc(&ihost->nr_scans); 597 } 598 ISCSI_DBG_TRANS_SESSION(session, "Completed unblocking session\n"); 599} 600 601/** 602 * iscsi_unblock_session - set a session as logged in and start IO. 603 * @session: iscsi session 604 * 605 * Mark a session as ready to accept IO. 606 */ 607void iscsi_unblock_session(struct iscsi_cls_session *session) 608{ 609 queue_work(iscsi_eh_timer_workq, &session->unblock_work); 610 /* 611 * make sure all the events have completed before tell the driver 612 * it is safe 613 */ 614 flush_workqueue(iscsi_eh_timer_workq); 615} 616EXPORT_SYMBOL_GPL(iscsi_unblock_session); 617 618static void __iscsi_block_session(struct work_struct *work) 619{ 620 struct iscsi_cls_session *session = 621 container_of(work, struct iscsi_cls_session, 622 block_work); 623 unsigned long flags; 624 625 ISCSI_DBG_TRANS_SESSION(session, "Blocking session\n"); 626 spin_lock_irqsave(&session->lock, flags); 627 session->state = ISCSI_SESSION_FAILED; 628 spin_unlock_irqrestore(&session->lock, flags); 629 scsi_target_block(&session->dev); 630 ISCSI_DBG_TRANS_SESSION(session, "Completed SCSI target blocking\n"); 631 if (session->recovery_tmo >= 0) 632 queue_delayed_work(iscsi_eh_timer_workq, 633 &session->recovery_work, 634 session->recovery_tmo * HZ); 635} 636 637void iscsi_block_session(struct iscsi_cls_session *session) 638{ 639 queue_work(iscsi_eh_timer_workq, &session->block_work); 640} 641EXPORT_SYMBOL_GPL(iscsi_block_session); 642 643static void __iscsi_unbind_session(struct work_struct *work) 644{ 645 struct iscsi_cls_session *session = 646 container_of(work, struct iscsi_cls_session, 647 unbind_work); 648 struct Scsi_Host *shost = iscsi_session_to_shost(session); 649 struct iscsi_cls_host *ihost = shost->shost_data; 650 unsigned long flags; 651 652 ISCSI_DBG_TRANS_SESSION(session, "Unbinding session\n"); 653 654 /* Prevent new scans and make sure scanning is not in progress */ 655 mutex_lock(&ihost->mutex); 656 spin_lock_irqsave(&session->lock, flags); 657 if (session->target_id == ISCSI_MAX_TARGET) { 658 spin_unlock_irqrestore(&session->lock, flags); 659 mutex_unlock(&ihost->mutex); 660 return; 661 } 662 session->target_id = ISCSI_MAX_TARGET; 663 spin_unlock_irqrestore(&session->lock, flags); 664 mutex_unlock(&ihost->mutex); 665 666 scsi_remove_target(&session->dev); 667 iscsi_session_event(session, ISCSI_KEVENT_UNBIND_SESSION); 668 ISCSI_DBG_TRANS_SESSION(session, "Completed target removal\n"); 669} 670 671struct iscsi_cls_session * 672iscsi_alloc_session(struct Scsi_Host *shost, struct iscsi_transport *transport, 673 int dd_size) 674{ 675 struct iscsi_cls_session *session; 676 677 session = kzalloc(sizeof(*session) + dd_size, 678 GFP_KERNEL); 679 if (!session) 680 return NULL; 681 682 session->transport = transport; 683 session->recovery_tmo = 120; 684 session->state = ISCSI_SESSION_FREE; 685 INIT_DELAYED_WORK(&session->recovery_work, session_recovery_timedout); 686 INIT_LIST_HEAD(&session->sess_list); 687 INIT_WORK(&session->unblock_work, __iscsi_unblock_session); 688 INIT_WORK(&session->block_work, __iscsi_block_session); 689 INIT_WORK(&session->unbind_work, __iscsi_unbind_session); 690 INIT_WORK(&session->scan_work, iscsi_scan_session); 691 spin_lock_init(&session->lock); 692 693 /* this is released in the dev's release function */ 694 scsi_host_get(shost); 695 session->dev.parent = &shost->shost_gendev; 696 session->dev.release = iscsi_session_release; 697 device_initialize(&session->dev); 698 if (dd_size) 699 session->dd_data = &session[1]; 700 701 ISCSI_DBG_TRANS_SESSION(session, "Completed session allocation\n"); 702 return session; 703} 704EXPORT_SYMBOL_GPL(iscsi_alloc_session); 705 706static int iscsi_get_next_target_id(struct device *dev, void *data) 707{ 708 struct iscsi_cls_session *session; 709 unsigned long flags; 710 int err = 0; 711 712 if (!iscsi_is_session_dev(dev)) 713 return 0; 714 715 session = iscsi_dev_to_session(dev); 716 spin_lock_irqsave(&session->lock, flags); 717 if (*((unsigned int *) data) == session->target_id) 718 err = -EEXIST; 719 spin_unlock_irqrestore(&session->lock, flags); 720 return err; 721} 722 723int iscsi_add_session(struct iscsi_cls_session *session, unsigned int target_id) 724{ 725 struct Scsi_Host *shost = iscsi_session_to_shost(session); 726 struct iscsi_cls_host *ihost; 727 unsigned long flags; 728 unsigned int id = target_id; 729 int err; 730 731 ihost = shost->shost_data; 732 session->sid = atomic_add_return(1, &iscsi_session_nr); 733 734 if (id == ISCSI_MAX_TARGET) { 735 for (id = 0; id < ISCSI_MAX_TARGET; id++) { 736 err = device_for_each_child(&shost->shost_gendev, &id, 737 iscsi_get_next_target_id); 738 if (!err) 739 break; 740 } 741 742 if (id == ISCSI_MAX_TARGET) { 743 iscsi_cls_session_printk(KERN_ERR, session, 744 "Too many iscsi targets. Max " 745 "number of targets is %d.\n", 746 ISCSI_MAX_TARGET - 1); 747 err = -EOVERFLOW; 748 goto release_host; 749 } 750 } 751 session->target_id = id; 752 753 dev_set_name(&session->dev, "session%u", session->sid); 754 err = device_add(&session->dev); 755 if (err) { 756 iscsi_cls_session_printk(KERN_ERR, session, 757 "could not register session's dev\n"); 758 goto release_host; 759 } 760 transport_register_device(&session->dev); 761 762 spin_lock_irqsave(&sesslock, flags); 763 list_add(&session->sess_list, &sesslist); 764 spin_unlock_irqrestore(&sesslock, flags); 765 766 iscsi_session_event(session, ISCSI_KEVENT_CREATE_SESSION); 767 ISCSI_DBG_TRANS_SESSION(session, "Completed session adding\n"); 768 return 0; 769 770release_host: 771 scsi_host_put(shost); 772 return err; 773} 774EXPORT_SYMBOL_GPL(iscsi_add_session); 775 776/** 777 * iscsi_create_session - create iscsi class session 778 * @shost: scsi host 779 * @transport: iscsi transport 780 * @dd_size: private driver data size 781 * @target_id: which target 782 * 783 * This can be called from a LLD or iscsi_transport. 784 */ 785struct iscsi_cls_session * 786iscsi_create_session(struct Scsi_Host *shost, struct iscsi_transport *transport, 787 int dd_size, unsigned int target_id) 788{ 789 struct iscsi_cls_session *session; 790 791 session = iscsi_alloc_session(shost, transport, dd_size); 792 if (!session) 793 return NULL; 794 795 if (iscsi_add_session(session, target_id)) { 796 iscsi_free_session(session); 797 return NULL; 798 } 799 return session; 800} 801EXPORT_SYMBOL_GPL(iscsi_create_session); 802 803static void iscsi_conn_release(struct device *dev) 804{ 805 struct iscsi_cls_conn *conn = iscsi_dev_to_conn(dev); 806 struct device *parent = conn->dev.parent; 807 808 ISCSI_DBG_TRANS_CONN(conn, "Releasing conn\n"); 809 kfree(conn); 810 put_device(parent); 811} 812 813static int iscsi_is_conn_dev(const struct device *dev) 814{ 815 return dev->release == iscsi_conn_release; 816} 817 818static int iscsi_iter_destroy_conn_fn(struct device *dev, void *data) 819{ 820 if (!iscsi_is_conn_dev(dev)) 821 return 0; 822 return iscsi_destroy_conn(iscsi_dev_to_conn(dev)); 823} 824 825void iscsi_remove_session(struct iscsi_cls_session *session) 826{ 827 struct Scsi_Host *shost = iscsi_session_to_shost(session); 828 unsigned long flags; 829 int err; 830 831 ISCSI_DBG_TRANS_SESSION(session, "Removing session\n"); 832 833 spin_lock_irqsave(&sesslock, flags); 834 list_del(&session->sess_list); 835 spin_unlock_irqrestore(&sesslock, flags); 836 837 /* make sure there are no blocks/unblocks queued */ 838 flush_workqueue(iscsi_eh_timer_workq); 839 /* make sure the timedout callout is not running */ 840 if (!cancel_delayed_work(&session->recovery_work)) 841 flush_workqueue(iscsi_eh_timer_workq); 842 /* 843 * If we are blocked let commands flow again. The lld or iscsi 844 * layer should set up the queuecommand to fail commands. 845 * We assume that LLD will not be calling block/unblock while 846 * removing the session. 847 */ 848 spin_lock_irqsave(&session->lock, flags); 849 session->state = ISCSI_SESSION_FREE; 850 spin_unlock_irqrestore(&session->lock, flags); 851 852 scsi_target_unblock(&session->dev); 853 /* flush running scans then delete devices */ 854 scsi_flush_work(shost); 855 __iscsi_unbind_session(&session->unbind_work); 856 857 /* hw iscsi may not have removed all connections from session */ 858 err = device_for_each_child(&session->dev, NULL, 859 iscsi_iter_destroy_conn_fn); 860 if (err) 861 iscsi_cls_session_printk(KERN_ERR, session, 862 "Could not delete all connections " 863 "for session. Error %d.\n", err); 864 865 transport_unregister_device(&session->dev); 866 867 ISCSI_DBG_TRANS_SESSION(session, "Completing session removal\n"); 868 device_del(&session->dev); 869} 870EXPORT_SYMBOL_GPL(iscsi_remove_session); 871 872void iscsi_free_session(struct iscsi_cls_session *session) 873{ 874 ISCSI_DBG_TRANS_SESSION(session, "Freeing session\n"); 875 iscsi_session_event(session, ISCSI_KEVENT_DESTROY_SESSION); 876 put_device(&session->dev); 877} 878EXPORT_SYMBOL_GPL(iscsi_free_session); 879 880/** 881 * iscsi_destroy_session - destroy iscsi session 882 * @session: iscsi_session 883 * 884 * Can be called by a LLD or iscsi_transport. There must not be 885 * any running connections. 886 */ 887int iscsi_destroy_session(struct iscsi_cls_session *session) 888{ 889 iscsi_remove_session(session); 890 ISCSI_DBG_TRANS_SESSION(session, "Completing session destruction\n"); 891 iscsi_free_session(session); 892 return 0; 893} 894EXPORT_SYMBOL_GPL(iscsi_destroy_session); 895 896/** 897 * iscsi_create_conn - create iscsi class connection 898 * @session: iscsi cls session 899 * @dd_size: private driver data size 900 * @cid: connection id 901 * 902 * This can be called from a LLD or iscsi_transport. The connection 903 * is child of the session so cid must be unique for all connections 904 * on the session. 905 * 906 * Since we do not support MCS, cid will normally be zero. In some cases 907 * for software iscsi we could be trying to preallocate a connection struct 908 * in which case there could be two connection structs and cid would be 909 * non-zero. 910 */ 911struct iscsi_cls_conn * 912iscsi_create_conn(struct iscsi_cls_session *session, int dd_size, uint32_t cid) 913{ 914 struct iscsi_transport *transport = session->transport; 915 struct iscsi_cls_conn *conn; 916 unsigned long flags; 917 int err; 918 919 conn = kzalloc(sizeof(*conn) + dd_size, GFP_KERNEL); 920 if (!conn) 921 return NULL; 922 if (dd_size) 923 conn->dd_data = &conn[1]; 924 925 INIT_LIST_HEAD(&conn->conn_list); 926 conn->transport = transport; 927 conn->cid = cid; 928 929 /* this is released in the dev's release function */ 930 if (!get_device(&session->dev)) 931 goto free_conn; 932 933 dev_set_name(&conn->dev, "connection%d:%u", session->sid, cid); 934 conn->dev.parent = &session->dev; 935 conn->dev.release = iscsi_conn_release; 936 err = device_register(&conn->dev); 937 if (err) { 938 iscsi_cls_session_printk(KERN_ERR, session, "could not " 939 "register connection's dev\n"); 940 goto release_parent_ref; 941 } 942 transport_register_device(&conn->dev); 943 944 spin_lock_irqsave(&connlock, flags); 945 list_add(&conn->conn_list, &connlist); 946 conn->active = 1; 947 spin_unlock_irqrestore(&connlock, flags); 948 949 ISCSI_DBG_TRANS_CONN(conn, "Completed conn creation\n"); 950 return conn; 951 952release_parent_ref: 953 put_device(&session->dev); 954free_conn: 955 kfree(conn); 956 return NULL; 957} 958 959EXPORT_SYMBOL_GPL(iscsi_create_conn); 960 961/** 962 * iscsi_destroy_conn - destroy iscsi class connection 963 * @conn: iscsi cls session 964 * 965 * This can be called from a LLD or iscsi_transport. 966 */ 967int iscsi_destroy_conn(struct iscsi_cls_conn *conn) 968{ 969 unsigned long flags; 970 971 spin_lock_irqsave(&connlock, flags); 972 conn->active = 0; 973 list_del(&conn->conn_list); 974 spin_unlock_irqrestore(&connlock, flags); 975 976 transport_unregister_device(&conn->dev); 977 ISCSI_DBG_TRANS_CONN(conn, "Completing conn destruction\n"); 978 device_unregister(&conn->dev); 979 return 0; 980} 981EXPORT_SYMBOL_GPL(iscsi_destroy_conn); 982 983/* 984 * iscsi interface functions 985 */ 986static struct iscsi_internal * 987iscsi_if_transport_lookup(struct iscsi_transport *tt) 988{ 989 struct iscsi_internal *priv; 990 unsigned long flags; 991 992 spin_lock_irqsave(&iscsi_transport_lock, flags); 993 list_for_each_entry(priv, &iscsi_transports, list) { 994 if (tt == priv->iscsi_transport) { 995 spin_unlock_irqrestore(&iscsi_transport_lock, flags); 996 return priv; 997 } 998 } 999 spin_unlock_irqrestore(&iscsi_transport_lock, flags); 1000 return NULL; 1001} 1002 1003static int 1004iscsi_multicast_skb(struct sk_buff *skb, uint32_t group, gfp_t gfp) 1005{ 1006 return nlmsg_multicast(nls, skb, 0, group, gfp); 1007} 1008 1009int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr, 1010 char *data, uint32_t data_size) 1011{ 1012 struct nlmsghdr *nlh; 1013 struct sk_buff *skb; 1014 struct iscsi_uevent *ev; 1015 char *pdu; 1016 struct iscsi_internal *priv; 1017 int len = NLMSG_SPACE(sizeof(*ev) + sizeof(struct iscsi_hdr) + 1018 data_size); 1019 1020 priv = iscsi_if_transport_lookup(conn->transport); 1021 if (!priv) 1022 return -EINVAL; 1023 1024 skb = alloc_skb(len, GFP_ATOMIC); 1025 if (!skb) { 1026 iscsi_conn_error_event(conn, ISCSI_ERR_CONN_FAILED); 1027 iscsi_cls_conn_printk(KERN_ERR, conn, "can not deliver " 1028 "control PDU: OOM\n"); 1029 return -ENOMEM; 1030 } 1031 1032 nlh = __nlmsg_put(skb, 0, 0, 0, (len - sizeof(*nlh)), 0); 1033 ev = NLMSG_DATA(nlh); 1034 memset(ev, 0, sizeof(*ev)); 1035 ev->transport_handle = iscsi_handle(conn->transport); 1036 ev->type = ISCSI_KEVENT_RECV_PDU; 1037 ev->r.recv_req.cid = conn->cid; 1038 ev->r.recv_req.sid = iscsi_conn_get_sid(conn); 1039 pdu = (char*)ev + sizeof(*ev); 1040 memcpy(pdu, hdr, sizeof(struct iscsi_hdr)); 1041 memcpy(pdu + sizeof(struct iscsi_hdr), data, data_size); 1042 1043 return iscsi_multicast_skb(skb, ISCSI_NL_GRP_ISCSID, GFP_ATOMIC); 1044} 1045EXPORT_SYMBOL_GPL(iscsi_recv_pdu); 1046 1047int iscsi_offload_mesg(struct Scsi_Host *shost, 1048 struct iscsi_transport *transport, uint32_t type, 1049 char *data, uint16_t data_size) 1050{ 1051 struct nlmsghdr *nlh; 1052 struct sk_buff *skb; 1053 struct iscsi_uevent *ev; 1054 int len = NLMSG_SPACE(sizeof(*ev) + data_size); 1055 1056 skb = alloc_skb(len, GFP_ATOMIC); 1057 if (!skb) { 1058 printk(KERN_ERR "can not deliver iscsi offload message:OOM\n"); 1059 return -ENOMEM; 1060 } 1061 1062 nlh = __nlmsg_put(skb, 0, 0, 0, (len - sizeof(*nlh)), 0); 1063 ev = NLMSG_DATA(nlh); 1064 memset(ev, 0, sizeof(*ev)); 1065 ev->type = type; 1066 ev->transport_handle = iscsi_handle(transport); 1067 switch (type) { 1068 case ISCSI_KEVENT_PATH_REQ: 1069 ev->r.req_path.host_no = shost->host_no; 1070 break; 1071 case ISCSI_KEVENT_IF_DOWN: 1072 ev->r.notify_if_down.host_no = shost->host_no; 1073 break; 1074 } 1075 1076 memcpy((char *)ev + sizeof(*ev), data, data_size); 1077 1078 return iscsi_multicast_skb(skb, ISCSI_NL_GRP_UIP, GFP_ATOMIC); 1079} 1080EXPORT_SYMBOL_GPL(iscsi_offload_mesg); 1081 1082void iscsi_conn_error_event(struct iscsi_cls_conn *conn, enum iscsi_err error) 1083{ 1084 struct nlmsghdr *nlh; 1085 struct sk_buff *skb; 1086 struct iscsi_uevent *ev; 1087 struct iscsi_internal *priv; 1088 int len = NLMSG_SPACE(sizeof(*ev)); 1089 1090 priv = iscsi_if_transport_lookup(conn->transport); 1091 if (!priv) 1092 return; 1093 1094 skb = alloc_skb(len, GFP_ATOMIC); 1095 if (!skb) { 1096 iscsi_cls_conn_printk(KERN_ERR, conn, "gracefully ignored " 1097 "conn error (%d)\n", error); 1098 return; 1099 } 1100 1101 nlh = __nlmsg_put(skb, 0, 0, 0, (len - sizeof(*nlh)), 0); 1102 ev = NLMSG_DATA(nlh); 1103 ev->transport_handle = iscsi_handle(conn->transport); 1104 ev->type = ISCSI_KEVENT_CONN_ERROR; 1105 ev->r.connerror.error = error; 1106 ev->r.connerror.cid = conn->cid; 1107 ev->r.connerror.sid = iscsi_conn_get_sid(conn); 1108 1109 iscsi_multicast_skb(skb, ISCSI_NL_GRP_ISCSID, GFP_ATOMIC); 1110 1111 iscsi_cls_conn_printk(KERN_INFO, conn, "detected conn error (%d)\n", 1112 error); 1113} 1114EXPORT_SYMBOL_GPL(iscsi_conn_error_event); 1115 1116static int 1117iscsi_if_send_reply(uint32_t group, int seq, int type, int done, int multi, 1118 void *payload, int size) 1119{ 1120 struct sk_buff *skb; 1121 struct nlmsghdr *nlh; 1122 int len = NLMSG_SPACE(size); 1123 int flags = multi ? NLM_F_MULTI : 0; 1124 int t = done ? NLMSG_DONE : type; 1125 1126 skb = alloc_skb(len, GFP_ATOMIC); 1127 if (!skb) { 1128 printk(KERN_ERR "Could not allocate skb to send reply.\n"); 1129 return -ENOMEM; 1130 } 1131 1132 nlh = __nlmsg_put(skb, 0, 0, t, (len - sizeof(*nlh)), 0); 1133 nlh->nlmsg_flags = flags; 1134 memcpy(NLMSG_DATA(nlh), payload, size); 1135 return iscsi_multicast_skb(skb, group, GFP_ATOMIC); 1136} 1137 1138static int 1139iscsi_if_get_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh) 1140{ 1141 struct iscsi_uevent *ev = NLMSG_DATA(nlh); 1142 struct iscsi_stats *stats; 1143 struct sk_buff *skbstat; 1144 struct iscsi_cls_conn *conn; 1145 struct nlmsghdr *nlhstat; 1146 struct iscsi_uevent *evstat; 1147 struct iscsi_internal *priv; 1148 int len = NLMSG_SPACE(sizeof(*ev) + 1149 sizeof(struct iscsi_stats) + 1150 sizeof(struct iscsi_stats_custom) * 1151 ISCSI_STATS_CUSTOM_MAX); 1152 int err = 0; 1153 1154 priv = iscsi_if_transport_lookup(transport); 1155 if (!priv) 1156 return -EINVAL; 1157 1158 conn = iscsi_conn_lookup(ev->u.get_stats.sid, ev->u.get_stats.cid); 1159 if (!conn) 1160 return -EEXIST; 1161 1162 do { 1163 int actual_size; 1164 1165 skbstat = alloc_skb(len, GFP_ATOMIC); 1166 if (!skbstat) { 1167 iscsi_cls_conn_printk(KERN_ERR, conn, "can not " 1168 "deliver stats: OOM\n"); 1169 return -ENOMEM; 1170 } 1171 1172 nlhstat = __nlmsg_put(skbstat, 0, 0, 0, 1173 (len - sizeof(*nlhstat)), 0); 1174 evstat = NLMSG_DATA(nlhstat); 1175 memset(evstat, 0, sizeof(*evstat)); 1176 evstat->transport_handle = iscsi_handle(conn->transport); 1177 evstat->type = nlh->nlmsg_type; 1178 evstat->u.get_stats.cid = 1179 ev->u.get_stats.cid; 1180 evstat->u.get_stats.sid = 1181 ev->u.get_stats.sid; 1182 stats = (struct iscsi_stats *) 1183 ((char*)evstat + sizeof(*evstat)); 1184 memset(stats, 0, sizeof(*stats)); 1185 1186 transport->get_stats(conn, stats); 1187 actual_size = NLMSG_SPACE(sizeof(struct iscsi_uevent) + 1188 sizeof(struct iscsi_stats) + 1189 sizeof(struct iscsi_stats_custom) * 1190 stats->custom_length); 1191 actual_size -= sizeof(*nlhstat); 1192 actual_size = NLMSG_LENGTH(actual_size); 1193 skb_trim(skbstat, NLMSG_ALIGN(actual_size)); 1194 nlhstat->nlmsg_len = actual_size; 1195 1196 err = iscsi_multicast_skb(skbstat, ISCSI_NL_GRP_ISCSID, 1197 GFP_ATOMIC); 1198 } while (err < 0 && err != -ECONNREFUSED); 1199 1200 return err; 1201} 1202 1203/** 1204 * iscsi_session_event - send session destr. completion event 1205 * @session: iscsi class session 1206 * @event: type of event 1207 */ 1208int iscsi_session_event(struct iscsi_cls_session *session, 1209 enum iscsi_uevent_e event) 1210{ 1211 struct iscsi_internal *priv; 1212 struct Scsi_Host *shost; 1213 struct iscsi_uevent *ev; 1214 struct sk_buff *skb; 1215 struct nlmsghdr *nlh; 1216 int rc, len = NLMSG_SPACE(sizeof(*ev)); 1217 1218 priv = iscsi_if_transport_lookup(session->transport); 1219 if (!priv) 1220 return -EINVAL; 1221 shost = iscsi_session_to_shost(session); 1222 1223 skb = alloc_skb(len, GFP_KERNEL); 1224 if (!skb) { 1225 iscsi_cls_session_printk(KERN_ERR, session, 1226 "Cannot notify userspace of session " 1227 "event %u\n", event); 1228 return -ENOMEM; 1229 } 1230 1231 nlh = __nlmsg_put(skb, 0, 0, 0, (len - sizeof(*nlh)), 0); 1232 ev = NLMSG_DATA(nlh); 1233 ev->transport_handle = iscsi_handle(session->transport); 1234 1235 ev->type = event; 1236 switch (event) { 1237 case ISCSI_KEVENT_DESTROY_SESSION: 1238 ev->r.d_session.host_no = shost->host_no; 1239 ev->r.d_session.sid = session->sid; 1240 break; 1241 case ISCSI_KEVENT_CREATE_SESSION: 1242 ev->r.c_session_ret.host_no = shost->host_no; 1243 ev->r.c_session_ret.sid = session->sid; 1244 break; 1245 case ISCSI_KEVENT_UNBIND_SESSION: 1246 ev->r.unbind_session.host_no = shost->host_no; 1247 ev->r.unbind_session.sid = session->sid; 1248 break; 1249 default: 1250 iscsi_cls_session_printk(KERN_ERR, session, "Invalid event " 1251 "%u.\n", event); 1252 kfree_skb(skb); 1253 return -EINVAL; 1254 } 1255 1256 /* 1257 * this will occur if the daemon is not up, so we just warn 1258 * the user and when the daemon is restarted it will handle it 1259 */ 1260 rc = iscsi_multicast_skb(skb, ISCSI_NL_GRP_ISCSID, GFP_KERNEL); 1261 if (rc == -ESRCH) 1262 iscsi_cls_session_printk(KERN_ERR, session, 1263 "Cannot notify userspace of session " 1264 "event %u. Check iscsi daemon\n", 1265 event); 1266 1267 ISCSI_DBG_TRANS_SESSION(session, "Completed handling event %d rc %d\n", 1268 event, rc); 1269 return rc; 1270} 1271EXPORT_SYMBOL_GPL(iscsi_session_event); 1272 1273static int 1274iscsi_if_create_session(struct iscsi_internal *priv, struct iscsi_endpoint *ep, 1275 struct iscsi_uevent *ev, uint32_t initial_cmdsn, 1276 uint16_t cmds_max, uint16_t queue_depth) 1277{ 1278 struct iscsi_transport *transport = priv->iscsi_transport; 1279 struct iscsi_cls_session *session; 1280 struct Scsi_Host *shost; 1281 1282 session = transport->create_session(ep, cmds_max, queue_depth, 1283 initial_cmdsn); 1284 if (!session) 1285 return -ENOMEM; 1286 1287 shost = iscsi_session_to_shost(session); 1288 ev->r.c_session_ret.host_no = shost->host_no; 1289 ev->r.c_session_ret.sid = session->sid; 1290 ISCSI_DBG_TRANS_SESSION(session, 1291 "Completed creating transport session\n"); 1292 return 0; 1293} 1294 1295static int 1296iscsi_if_create_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev) 1297{ 1298 struct iscsi_cls_conn *conn; 1299 struct iscsi_cls_session *session; 1300 1301 session = iscsi_session_lookup(ev->u.c_conn.sid); 1302 if (!session) { 1303 printk(KERN_ERR "iscsi: invalid session %d.\n", 1304 ev->u.c_conn.sid); 1305 return -EINVAL; 1306 } 1307 1308 conn = transport->create_conn(session, ev->u.c_conn.cid); 1309 if (!conn) { 1310 iscsi_cls_session_printk(KERN_ERR, session, 1311 "couldn't create a new connection."); 1312 return -ENOMEM; 1313 } 1314 1315 ev->r.c_conn_ret.sid = session->sid; 1316 ev->r.c_conn_ret.cid = conn->cid; 1317 1318 ISCSI_DBG_TRANS_CONN(conn, "Completed creating transport conn\n"); 1319 return 0; 1320} 1321 1322static int 1323iscsi_if_destroy_conn(struct iscsi_transport *transport, struct iscsi_uevent *ev) 1324{ 1325 struct iscsi_cls_conn *conn; 1326 1327 conn = iscsi_conn_lookup(ev->u.d_conn.sid, ev->u.d_conn.cid); 1328 if (!conn) 1329 return -EINVAL; 1330 1331 ISCSI_DBG_TRANS_CONN(conn, "Destroying transport conn\n"); 1332 if (transport->destroy_conn) 1333 transport->destroy_conn(conn); 1334 1335 return 0; 1336} 1337 1338static int 1339iscsi_set_param(struct iscsi_transport *transport, struct iscsi_uevent *ev) 1340{ 1341 char *data = (char*)ev + sizeof(*ev); 1342 struct iscsi_cls_conn *conn; 1343 struct iscsi_cls_session *session; 1344 int err = 0, value = 0; 1345 1346 session = iscsi_session_lookup(ev->u.set_param.sid); 1347 conn = iscsi_conn_lookup(ev->u.set_param.sid, ev->u.set_param.cid); 1348 if (!conn || !session) 1349 return -EINVAL; 1350 1351 switch (ev->u.set_param.param) { 1352 case ISCSI_PARAM_SESS_RECOVERY_TMO: 1353 sscanf(data, "%d", &value); 1354 session->recovery_tmo = value; 1355 break; 1356 default: 1357 err = transport->set_param(conn, ev->u.set_param.param, 1358 data, ev->u.set_param.len); 1359 } 1360 1361 return err; 1362} 1363 1364static int iscsi_if_ep_connect(struct iscsi_transport *transport, 1365 struct iscsi_uevent *ev, int msg_type) 1366{ 1367 struct iscsi_endpoint *ep; 1368 struct sockaddr *dst_addr; 1369 struct Scsi_Host *shost = NULL; 1370 int non_blocking, err = 0; 1371 1372 if (!transport->ep_connect) 1373 return -EINVAL; 1374 1375 if (msg_type == ISCSI_UEVENT_TRANSPORT_EP_CONNECT_THROUGH_HOST) { 1376 shost = scsi_host_lookup(ev->u.ep_connect_through_host.host_no); 1377 if (!shost) { 1378 printk(KERN_ERR "ep connect failed. Could not find " 1379 "host no %u\n", 1380 ev->u.ep_connect_through_host.host_no); 1381 return -ENODEV; 1382 } 1383 non_blocking = ev->u.ep_connect_through_host.non_blocking; 1384 } else 1385 non_blocking = ev->u.ep_connect.non_blocking; 1386 1387 dst_addr = (struct sockaddr *)((char*)ev + sizeof(*ev)); 1388 ep = transport->ep_connect(shost, dst_addr, non_blocking); 1389 if (IS_ERR(ep)) { 1390 err = PTR_ERR(ep); 1391 goto release_host; 1392 } 1393 1394 ev->r.ep_connect_ret.handle = ep->id; 1395release_host: 1396 if (shost) 1397 scsi_host_put(shost); 1398 return err; 1399} 1400 1401static int 1402iscsi_if_transport_ep(struct iscsi_transport *transport, 1403 struct iscsi_uevent *ev, int msg_type) 1404{ 1405 struct iscsi_endpoint *ep; 1406 int rc = 0; 1407 1408 switch (msg_type) { 1409 case ISCSI_UEVENT_TRANSPORT_EP_CONNECT_THROUGH_HOST: 1410 case ISCSI_UEVENT_TRANSPORT_EP_CONNECT: 1411 rc = iscsi_if_ep_connect(transport, ev, msg_type); 1412 break; 1413 case ISCSI_UEVENT_TRANSPORT_EP_POLL: 1414 if (!transport->ep_poll) 1415 return -EINVAL; 1416 1417 ep = iscsi_lookup_endpoint(ev->u.ep_poll.ep_handle); 1418 if (!ep) 1419 return -EINVAL; 1420 1421 ev->r.retcode = transport->ep_poll(ep, 1422 ev->u.ep_poll.timeout_ms); 1423 break; 1424 case ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT: 1425 if (!transport->ep_disconnect) 1426 return -EINVAL; 1427 1428 ep = iscsi_lookup_endpoint(ev->u.ep_disconnect.ep_handle); 1429 if (!ep) 1430 return -EINVAL; 1431 1432 transport->ep_disconnect(ep); 1433 break; 1434 } 1435 return rc; 1436} 1437 1438static int 1439iscsi_tgt_dscvr(struct iscsi_transport *transport, 1440 struct iscsi_uevent *ev) 1441{ 1442 struct Scsi_Host *shost; 1443 struct sockaddr *dst_addr; 1444 int err; 1445 1446 if (!transport->tgt_dscvr) 1447 return -EINVAL; 1448 1449 shost = scsi_host_lookup(ev->u.tgt_dscvr.host_no); 1450 if (!shost) { 1451 printk(KERN_ERR "target discovery could not find host no %u\n", 1452 ev->u.tgt_dscvr.host_no); 1453 return -ENODEV; 1454 } 1455 1456 1457 dst_addr = (struct sockaddr *)((char*)ev + sizeof(*ev)); 1458 err = transport->tgt_dscvr(shost, ev->u.tgt_dscvr.type, 1459 ev->u.tgt_dscvr.enable, dst_addr); 1460 scsi_host_put(shost); 1461 return err; 1462} 1463 1464static int 1465iscsi_set_host_param(struct iscsi_transport *transport, 1466 struct iscsi_uevent *ev) 1467{ 1468 char *data = (char*)ev + sizeof(*ev); 1469 struct Scsi_Host *shost; 1470 int err; 1471 1472 if (!transport->set_host_param) 1473 return -ENOSYS; 1474 1475 shost = scsi_host_lookup(ev->u.set_host_param.host_no); 1476 if (!shost) { 1477 printk(KERN_ERR "set_host_param could not find host no %u\n", 1478 ev->u.set_host_param.host_no); 1479 return -ENODEV; 1480 } 1481 1482 err = transport->set_host_param(shost, ev->u.set_host_param.param, 1483 data, ev->u.set_host_param.len); 1484 scsi_host_put(shost); 1485 return err; 1486} 1487 1488static int 1489iscsi_set_path(struct iscsi_transport *transport, struct iscsi_uevent *ev) 1490{ 1491 struct Scsi_Host *shost; 1492 struct iscsi_path *params; 1493 int err; 1494 1495 if (!transport->set_path) 1496 return -ENOSYS; 1497 1498 shost = scsi_host_lookup(ev->u.set_path.host_no); 1499 if (!shost) { 1500 printk(KERN_ERR "set path could not find host no %u\n", 1501 ev->u.set_path.host_no); 1502 return -ENODEV; 1503 } 1504 1505 params = (struct iscsi_path *)((char *)ev + sizeof(*ev)); 1506 err = transport->set_path(shost, params); 1507 1508 scsi_host_put(shost); 1509 return err; 1510} 1511 1512static int 1513iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, uint32_t *group) 1514{ 1515 int err = 0; 1516 struct iscsi_uevent *ev = NLMSG_DATA(nlh); 1517 struct iscsi_transport *transport = NULL; 1518 struct iscsi_internal *priv; 1519 struct iscsi_cls_session *session; 1520 struct iscsi_cls_conn *conn; 1521 struct iscsi_endpoint *ep = NULL; 1522 1523 if (nlh->nlmsg_type == ISCSI_UEVENT_PATH_UPDATE) 1524 *group = ISCSI_NL_GRP_UIP; 1525 else 1526 *group = ISCSI_NL_GRP_ISCSID; 1527 1528 priv = iscsi_if_transport_lookup(iscsi_ptr(ev->transport_handle)); 1529 if (!priv) 1530 return -EINVAL; 1531 transport = priv->iscsi_transport; 1532 1533 if (!try_module_get(transport->owner)) 1534 return -EINVAL; 1535 1536 switch (nlh->nlmsg_type) { 1537 case ISCSI_UEVENT_CREATE_SESSION: 1538 err = iscsi_if_create_session(priv, ep, ev, 1539 ev->u.c_session.initial_cmdsn, 1540 ev->u.c_session.cmds_max, 1541 ev->u.c_session.queue_depth); 1542 break; 1543 case ISCSI_UEVENT_CREATE_BOUND_SESSION: 1544 ep = iscsi_lookup_endpoint(ev->u.c_bound_session.ep_handle); 1545 if (!ep) { 1546 err = -EINVAL; 1547 break; 1548 } 1549 1550 err = iscsi_if_create_session(priv, ep, ev, 1551 ev->u.c_bound_session.initial_cmdsn, 1552 ev->u.c_bound_session.cmds_max, 1553 ev->u.c_bound_session.queue_depth); 1554 break; 1555 case ISCSI_UEVENT_DESTROY_SESSION: 1556 session = iscsi_session_lookup(ev->u.d_session.sid); 1557 if (session) 1558 transport->destroy_session(session); 1559 else 1560 err = -EINVAL; 1561 break; 1562 case ISCSI_UEVENT_UNBIND_SESSION: 1563 session = iscsi_session_lookup(ev->u.d_session.sid); 1564 if (session) 1565 scsi_queue_work(iscsi_session_to_shost(session), 1566 &session->unbind_work); 1567 else 1568 err = -EINVAL; 1569 break; 1570 case ISCSI_UEVENT_CREATE_CONN: 1571 err = iscsi_if_create_conn(transport, ev); 1572 break; 1573 case ISCSI_UEVENT_DESTROY_CONN: 1574 err = iscsi_if_destroy_conn(transport, ev); 1575 break; 1576 case ISCSI_UEVENT_BIND_CONN: 1577 session = iscsi_session_lookup(ev->u.b_conn.sid); 1578 conn = iscsi_conn_lookup(ev->u.b_conn.sid, ev->u.b_conn.cid); 1579 1580 if (session && conn) 1581 ev->r.retcode = transport->bind_conn(session, conn, 1582 ev->u.b_conn.transport_eph, 1583 ev->u.b_conn.is_leading); 1584 else 1585 err = -EINVAL; 1586 break; 1587 case ISCSI_UEVENT_SET_PARAM: 1588 err = iscsi_set_param(transport, ev); 1589 break; 1590 case ISCSI_UEVENT_START_CONN: 1591 conn = iscsi_conn_lookup(ev->u.start_conn.sid, ev->u.start_conn.cid); 1592 if (conn) 1593 ev->r.retcode = transport->start_conn(conn); 1594 else 1595 err = -EINVAL; 1596 break; 1597 case ISCSI_UEVENT_STOP_CONN: 1598 conn = iscsi_conn_lookup(ev->u.stop_conn.sid, ev->u.stop_conn.cid); 1599 if (conn) 1600 transport->stop_conn(conn, ev->u.stop_conn.flag); 1601 else 1602 err = -EINVAL; 1603 break; 1604 case ISCSI_UEVENT_SEND_PDU: 1605 conn = iscsi_conn_lookup(ev->u.send_pdu.sid, ev->u.send_pdu.cid); 1606 if (conn) 1607 ev->r.retcode = transport->send_pdu(conn, 1608 (struct iscsi_hdr*)((char*)ev + sizeof(*ev)), 1609 (char*)ev + sizeof(*ev) + ev->u.send_pdu.hdr_size, 1610 ev->u.send_pdu.data_size); 1611 else 1612 err = -EINVAL; 1613 break; 1614 case ISCSI_UEVENT_GET_STATS: 1615 err = iscsi_if_get_stats(transport, nlh); 1616 break; 1617 case ISCSI_UEVENT_TRANSPORT_EP_CONNECT: 1618 case ISCSI_UEVENT_TRANSPORT_EP_POLL: 1619 case ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT: 1620 case ISCSI_UEVENT_TRANSPORT_EP_CONNECT_THROUGH_HOST: 1621 err = iscsi_if_transport_ep(transport, ev, nlh->nlmsg_type); 1622 break; 1623 case ISCSI_UEVENT_TGT_DSCVR: 1624 err = iscsi_tgt_dscvr(transport, ev); 1625 break; 1626 case ISCSI_UEVENT_SET_HOST_PARAM: 1627 err = iscsi_set_host_param(transport, ev); 1628 break; 1629 case ISCSI_UEVENT_PATH_UPDATE: 1630 err = iscsi_set_path(transport, ev); 1631 break; 1632 default: 1633 err = -ENOSYS; 1634 break; 1635 } 1636 1637 module_put(transport->owner); 1638 return err; 1639} 1640 1641/* 1642 * Get message from skb. Each message is processed by iscsi_if_recv_msg. 1643 * Malformed skbs with wrong lengths or invalid creds are not processed. 1644 */ 1645static void 1646iscsi_if_rx(struct sk_buff *skb) 1647{ 1648 mutex_lock(&rx_queue_mutex); 1649 while (skb->len >= NLMSG_SPACE(0)) { 1650 int err; 1651 uint32_t rlen; 1652 struct nlmsghdr *nlh; 1653 struct iscsi_uevent *ev; 1654 uint32_t group; 1655 1656 nlh = nlmsg_hdr(skb); 1657 if (nlh->nlmsg_len < sizeof(*nlh) || 1658 skb->len < nlh->nlmsg_len) { 1659 break; 1660 } 1661 1662 ev = NLMSG_DATA(nlh); 1663 rlen = NLMSG_ALIGN(nlh->nlmsg_len); 1664 if (rlen > skb->len) 1665 rlen = skb->len; 1666 1667 err = iscsi_if_recv_msg(skb, nlh, &group); 1668 if (err) { 1669 ev->type = ISCSI_KEVENT_IF_ERROR; 1670 ev->iferror = err; 1671 } 1672 do { 1673 /* 1674 * special case for GET_STATS: 1675 * on success - sending reply and stats from 1676 * inside of if_recv_msg(), 1677 * on error - fall through. 1678 */ 1679 if (ev->type == ISCSI_UEVENT_GET_STATS && !err) 1680 break; 1681 err = iscsi_if_send_reply(group, nlh->nlmsg_seq, 1682 nlh->nlmsg_type, 0, 0, ev, sizeof(*ev)); 1683 } while (err < 0 && err != -ECONNREFUSED); 1684 skb_pull(skb, rlen); 1685 } 1686 mutex_unlock(&rx_queue_mutex); 1687} 1688 1689#define ISCSI_CLASS_ATTR(_prefix,_name,_mode,_show,_store) \ 1690struct device_attribute dev_attr_##_prefix##_##_name = \ 1691 __ATTR(_name,_mode,_show,_store) 1692 1693/* 1694 * iSCSI connection attrs 1695 */ 1696#define iscsi_conn_attr_show(param) \ 1697static ssize_t \ 1698show_conn_param_##param(struct device *dev, \ 1699 struct device_attribute *attr, char *buf) \ 1700{ \ 1701 struct iscsi_cls_conn *conn = iscsi_dev_to_conn(dev->parent); \ 1702 struct iscsi_transport *t = conn->transport; \ 1703 return t->get_conn_param(conn, param, buf); \ 1704} 1705 1706#define iscsi_conn_attr(field, param) \ 1707 iscsi_conn_attr_show(param) \ 1708static ISCSI_CLASS_ATTR(conn, field, S_IRUGO, show_conn_param_##param, \ 1709 NULL); 1710 1711iscsi_conn_attr(max_recv_dlength, ISCSI_PARAM_MAX_RECV_DLENGTH); 1712iscsi_conn_attr(max_xmit_dlength, ISCSI_PARAM_MAX_XMIT_DLENGTH); 1713iscsi_conn_attr(header_digest, ISCSI_PARAM_HDRDGST_EN); 1714iscsi_conn_attr(data_digest, ISCSI_PARAM_DATADGST_EN); 1715iscsi_conn_attr(ifmarker, ISCSI_PARAM_IFMARKER_EN); 1716iscsi_conn_attr(ofmarker, ISCSI_PARAM_OFMARKER_EN); 1717iscsi_conn_attr(persistent_port, ISCSI_PARAM_PERSISTENT_PORT); 1718iscsi_conn_attr(port, ISCSI_PARAM_CONN_PORT); 1719iscsi_conn_attr(exp_statsn, ISCSI_PARAM_EXP_STATSN); 1720iscsi_conn_attr(persistent_address, ISCSI_PARAM_PERSISTENT_ADDRESS); 1721iscsi_conn_attr(address, ISCSI_PARAM_CONN_ADDRESS); 1722iscsi_conn_attr(ping_tmo, ISCSI_PARAM_PING_TMO); 1723iscsi_conn_attr(recv_tmo, ISCSI_PARAM_RECV_TMO); 1724 1725/* 1726 * iSCSI session attrs 1727 */ 1728#define iscsi_session_attr_show(param, perm) \ 1729static ssize_t \ 1730show_session_param_##param(struct device *dev, \ 1731 struct device_attribute *attr, char *buf) \ 1732{ \ 1733 struct iscsi_cls_session *session = \ 1734 iscsi_dev_to_session(dev->parent); \ 1735 struct iscsi_transport *t = session->transport; \ 1736 \ 1737 if (perm && !capable(CAP_SYS_ADMIN)) \ 1738 return -EACCES; \ 1739 return t->get_session_param(session, param, buf); \ 1740} 1741 1742#define iscsi_session_attr(field, param, perm) \ 1743 iscsi_session_attr_show(param, perm) \ 1744static ISCSI_CLASS_ATTR(sess, field, S_IRUGO, show_session_param_##param, \ 1745 NULL); 1746 1747iscsi_session_attr(targetname, ISCSI_PARAM_TARGET_NAME, 0); 1748iscsi_session_attr(initial_r2t, ISCSI_PARAM_INITIAL_R2T_EN, 0); 1749iscsi_session_attr(max_outstanding_r2t, ISCSI_PARAM_MAX_R2T, 0); 1750iscsi_session_attr(immediate_data, ISCSI_PARAM_IMM_DATA_EN, 0); 1751iscsi_session_attr(first_burst_len, ISCSI_PARAM_FIRST_BURST, 0); 1752iscsi_session_attr(max_burst_len, ISCSI_PARAM_MAX_BURST, 0); 1753iscsi_session_attr(data_pdu_in_order, ISCSI_PARAM_PDU_INORDER_EN, 0); 1754iscsi_session_attr(data_seq_in_order, ISCSI_PARAM_DATASEQ_INORDER_EN, 0); 1755iscsi_session_attr(erl, ISCSI_PARAM_ERL, 0); 1756iscsi_session_attr(tpgt, ISCSI_PARAM_TPGT, 0); 1757iscsi_session_attr(username, ISCSI_PARAM_USERNAME, 1); 1758iscsi_session_attr(username_in, ISCSI_PARAM_USERNAME_IN, 1); 1759iscsi_session_attr(password, ISCSI_PARAM_PASSWORD, 1); 1760iscsi_session_attr(password_in, ISCSI_PARAM_PASSWORD_IN, 1); 1761iscsi_session_attr(fast_abort, ISCSI_PARAM_FAST_ABORT, 0); 1762iscsi_session_attr(abort_tmo, ISCSI_PARAM_ABORT_TMO, 0); 1763iscsi_session_attr(lu_reset_tmo, ISCSI_PARAM_LU_RESET_TMO, 0); 1764iscsi_session_attr(tgt_reset_tmo, ISCSI_PARAM_TGT_RESET_TMO, 0); 1765iscsi_session_attr(ifacename, ISCSI_PARAM_IFACE_NAME, 0); 1766iscsi_session_attr(initiatorname, ISCSI_PARAM_INITIATOR_NAME, 0) 1767 1768static ssize_t 1769show_priv_session_state(struct device *dev, struct device_attribute *attr, 1770 char *buf) 1771{ 1772 struct iscsi_cls_session *session = iscsi_dev_to_session(dev->parent); 1773 return sprintf(buf, "%s\n", iscsi_session_state_name(session->state)); 1774} 1775static ISCSI_CLASS_ATTR(priv_sess, state, S_IRUGO, show_priv_session_state, 1776 NULL); 1777 1778#define iscsi_priv_session_attr_show(field, format) \ 1779static ssize_t \ 1780show_priv_session_##field(struct device *dev, \ 1781 struct device_attribute *attr, char *buf) \ 1782{ \ 1783 struct iscsi_cls_session *session = \ 1784 iscsi_dev_to_session(dev->parent); \ 1785 return sprintf(buf, format"\n", session->field); \ 1786} 1787 1788#define iscsi_priv_session_attr(field, format) \ 1789 iscsi_priv_session_attr_show(field, format) \ 1790static ISCSI_CLASS_ATTR(priv_sess, field, S_IRUGO, show_priv_session_##field, \ 1791 NULL) 1792iscsi_priv_session_attr(recovery_tmo, "%d"); 1793 1794/* 1795 * iSCSI host attrs 1796 */ 1797#define iscsi_host_attr_show(param) \ 1798static ssize_t \ 1799show_host_param_##param(struct device *dev, \ 1800 struct device_attribute *attr, char *buf) \ 1801{ \ 1802 struct Scsi_Host *shost = transport_class_to_shost(dev); \ 1803 struct iscsi_internal *priv = to_iscsi_internal(shost->transportt); \ 1804 return priv->iscsi_transport->get_host_param(shost, param, buf); \ 1805} 1806 1807#define iscsi_host_attr(field, param) \ 1808 iscsi_host_attr_show(param) \ 1809static ISCSI_CLASS_ATTR(host, field, S_IRUGO, show_host_param_##param, \ 1810 NULL); 1811 1812iscsi_host_attr(netdev, ISCSI_HOST_PARAM_NETDEV_NAME); 1813iscsi_host_attr(hwaddress, ISCSI_HOST_PARAM_HWADDRESS); 1814iscsi_host_attr(ipaddress, ISCSI_HOST_PARAM_IPADDRESS); 1815iscsi_host_attr(initiatorname, ISCSI_HOST_PARAM_INITIATOR_NAME); 1816 1817#define SETUP_PRIV_SESSION_RD_ATTR(field) \ 1818do { \ 1819 priv->session_attrs[count] = &dev_attr_priv_sess_##field; \ 1820 count++; \ 1821} while (0) 1822 1823 1824#define SETUP_SESSION_RD_ATTR(field, param_flag) \ 1825do { \ 1826 if (tt->param_mask & param_flag) { \ 1827 priv->session_attrs[count] = &dev_attr_sess_##field; \ 1828 count++; \ 1829 } \ 1830} while (0) 1831 1832#define SETUP_CONN_RD_ATTR(field, param_flag) \ 1833do { \ 1834 if (tt->param_mask & param_flag) { \ 1835 priv->conn_attrs[count] = &dev_attr_conn_##field; \ 1836 count++; \ 1837 } \ 1838} while (0) 1839 1840#define SETUP_HOST_RD_ATTR(field, param_flag) \ 1841do { \ 1842 if (tt->host_param_mask & param_flag) { \ 1843 priv->host_attrs[count] = &dev_attr_host_##field; \ 1844 count++; \ 1845 } \ 1846} while (0) 1847 1848static int iscsi_session_match(struct attribute_container *cont, 1849 struct device *dev) 1850{ 1851 struct iscsi_cls_session *session; 1852 struct Scsi_Host *shost; 1853 struct iscsi_internal *priv; 1854 1855 if (!iscsi_is_session_dev(dev)) 1856 return 0; 1857 1858 session = iscsi_dev_to_session(dev); 1859 shost = iscsi_session_to_shost(session); 1860 if (!shost->transportt) 1861 return 0; 1862 1863 priv = to_iscsi_internal(shost->transportt); 1864 if (priv->session_cont.ac.class != &iscsi_session_class.class) 1865 return 0; 1866 1867 return &priv->session_cont.ac == cont; 1868} 1869 1870static int iscsi_conn_match(struct attribute_container *cont, 1871 struct device *dev) 1872{ 1873 struct iscsi_cls_session *session; 1874 struct iscsi_cls_conn *conn; 1875 struct Scsi_Host *shost; 1876 struct iscsi_internal *priv; 1877 1878 if (!iscsi_is_conn_dev(dev)) 1879 return 0; 1880 1881 conn = iscsi_dev_to_conn(dev); 1882 session = iscsi_dev_to_session(conn->dev.parent); 1883 shost = iscsi_session_to_shost(session); 1884 1885 if (!shost->transportt) 1886 return 0; 1887 1888 priv = to_iscsi_internal(shost->transportt); 1889 if (priv->conn_cont.ac.class != &iscsi_connection_class.class) 1890 return 0; 1891 1892 return &priv->conn_cont.ac == cont; 1893} 1894 1895static int iscsi_host_match(struct attribute_container *cont, 1896 struct device *dev) 1897{ 1898 struct Scsi_Host *shost; 1899 struct iscsi_internal *priv; 1900 1901 if (!scsi_is_host_device(dev)) 1902 return 0; 1903 1904 shost = dev_to_shost(dev); 1905 if (!shost->transportt || 1906 shost->transportt->host_attrs.ac.class != &iscsi_host_class.class) 1907 return 0; 1908 1909 priv = to_iscsi_internal(shost->transportt); 1910 return &priv->t.host_attrs.ac == cont; 1911} 1912 1913struct scsi_transport_template * 1914iscsi_register_transport(struct iscsi_transport *tt) 1915{ 1916 struct iscsi_internal *priv; 1917 unsigned long flags; 1918 int count = 0, err; 1919 1920 BUG_ON(!tt); 1921 1922 priv = iscsi_if_transport_lookup(tt); 1923 if (priv) 1924 return NULL; 1925 1926 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 1927 if (!priv) 1928 return NULL; 1929 INIT_LIST_HEAD(&priv->list); 1930 priv->iscsi_transport = tt; 1931 priv->t.user_scan = iscsi_user_scan; 1932 priv->t.create_work_queue = 1; 1933 1934 priv->dev.class = &iscsi_transport_class; 1935 dev_set_name(&priv->dev, "%s", tt->name); 1936 err = device_register(&priv->dev); 1937 if (err) 1938 goto free_priv; 1939 1940 err = sysfs_create_group(&priv->dev.kobj, &iscsi_transport_group); 1941 if (err) 1942 goto unregister_dev; 1943 1944 /* host parameters */ 1945 priv->t.host_attrs.ac.attrs = &priv->host_attrs[0]; 1946 priv->t.host_attrs.ac.class = &iscsi_host_class.class; 1947 priv->t.host_attrs.ac.match = iscsi_host_match; 1948 priv->t.host_size = sizeof(struct iscsi_cls_host); 1949 transport_container_register(&priv->t.host_attrs); 1950 1951 SETUP_HOST_RD_ATTR(netdev, ISCSI_HOST_NETDEV_NAME); 1952 SETUP_HOST_RD_ATTR(ipaddress, ISCSI_HOST_IPADDRESS); 1953 SETUP_HOST_RD_ATTR(hwaddress, ISCSI_HOST_HWADDRESS); 1954 SETUP_HOST_RD_ATTR(initiatorname, ISCSI_HOST_INITIATOR_NAME); 1955 BUG_ON(count > ISCSI_HOST_ATTRS); 1956 priv->host_attrs[count] = NULL; 1957 count = 0; 1958 1959 /* connection parameters */ 1960 priv->conn_cont.ac.attrs = &priv->conn_attrs[0]; 1961 priv->conn_cont.ac.class = &iscsi_connection_class.class; 1962 priv->conn_cont.ac.match = iscsi_conn_match; 1963 transport_container_register(&priv->conn_cont); 1964 1965 SETUP_CONN_RD_ATTR(max_recv_dlength, ISCSI_MAX_RECV_DLENGTH); 1966 SETUP_CONN_RD_ATTR(max_xmit_dlength, ISCSI_MAX_XMIT_DLENGTH); 1967 SETUP_CONN_RD_ATTR(header_digest, ISCSI_HDRDGST_EN); 1968 SETUP_CONN_RD_ATTR(data_digest, ISCSI_DATADGST_EN); 1969 SETUP_CONN_RD_ATTR(ifmarker, ISCSI_IFMARKER_EN); 1970 SETUP_CONN_RD_ATTR(ofmarker, ISCSI_OFMARKER_EN); 1971 SETUP_CONN_RD_ATTR(address, ISCSI_CONN_ADDRESS); 1972 SETUP_CONN_RD_ATTR(port, ISCSI_CONN_PORT); 1973 SETUP_CONN_RD_ATTR(exp_statsn, ISCSI_EXP_STATSN); 1974 SETUP_CONN_RD_ATTR(persistent_address, ISCSI_PERSISTENT_ADDRESS); 1975 SETUP_CONN_RD_ATTR(persistent_port, ISCSI_PERSISTENT_PORT); 1976 SETUP_CONN_RD_ATTR(ping_tmo, ISCSI_PING_TMO); 1977 SETUP_CONN_RD_ATTR(recv_tmo, ISCSI_RECV_TMO); 1978 1979 BUG_ON(count > ISCSI_CONN_ATTRS); 1980 priv->conn_attrs[count] = NULL; 1981 count = 0; 1982 1983 /* session parameters */ 1984 priv->session_cont.ac.attrs = &priv->session_attrs[0]; 1985 priv->session_cont.ac.class = &iscsi_session_class.class; 1986 priv->session_cont.ac.match = iscsi_session_match; 1987 transport_container_register(&priv->session_cont); 1988 1989 SETUP_SESSION_RD_ATTR(initial_r2t, ISCSI_INITIAL_R2T_EN); 1990 SETUP_SESSION_RD_ATTR(max_outstanding_r2t, ISCSI_MAX_R2T); 1991 SETUP_SESSION_RD_ATTR(immediate_data, ISCSI_IMM_DATA_EN); 1992 SETUP_SESSION_RD_ATTR(first_burst_len, ISCSI_FIRST_BURST); 1993 SETUP_SESSION_RD_ATTR(max_burst_len, ISCSI_MAX_BURST); 1994 SETUP_SESSION_RD_ATTR(data_pdu_in_order, ISCSI_PDU_INORDER_EN); 1995 SETUP_SESSION_RD_ATTR(data_seq_in_order, ISCSI_DATASEQ_INORDER_EN); 1996 SETUP_SESSION_RD_ATTR(erl, ISCSI_ERL); 1997 SETUP_SESSION_RD_ATTR(targetname, ISCSI_TARGET_NAME); 1998 SETUP_SESSION_RD_ATTR(tpgt, ISCSI_TPGT); 1999 SETUP_SESSION_RD_ATTR(password, ISCSI_USERNAME); 2000 SETUP_SESSION_RD_ATTR(password_in, ISCSI_USERNAME_IN); 2001 SETUP_SESSION_RD_ATTR(username, ISCSI_PASSWORD); 2002 SETUP_SESSION_RD_ATTR(username_in, ISCSI_PASSWORD_IN); 2003 SETUP_SESSION_RD_ATTR(fast_abort, ISCSI_FAST_ABORT); 2004 SETUP_SESSION_RD_ATTR(abort_tmo, ISCSI_ABORT_TMO); 2005 SETUP_SESSION_RD_ATTR(lu_reset_tmo,ISCSI_LU_RESET_TMO); 2006 SETUP_SESSION_RD_ATTR(tgt_reset_tmo,ISCSI_TGT_RESET_TMO); 2007 SETUP_SESSION_RD_ATTR(ifacename, ISCSI_IFACE_NAME); 2008 SETUP_SESSION_RD_ATTR(initiatorname, ISCSI_INITIATOR_NAME); 2009 SETUP_PRIV_SESSION_RD_ATTR(recovery_tmo); 2010 SETUP_PRIV_SESSION_RD_ATTR(state); 2011 2012 BUG_ON(count > ISCSI_SESSION_ATTRS); 2013 priv->session_attrs[count] = NULL; 2014 2015 spin_lock_irqsave(&iscsi_transport_lock, flags); 2016 list_add(&priv->list, &iscsi_transports); 2017 spin_unlock_irqrestore(&iscsi_transport_lock, flags); 2018 2019 printk(KERN_NOTICE "iscsi: registered transport (%s)\n", tt->name); 2020 return &priv->t; 2021 2022unregister_dev: 2023 device_unregister(&priv->dev); 2024 return NULL; 2025free_priv: 2026 kfree(priv); 2027 return NULL; 2028} 2029EXPORT_SYMBOL_GPL(iscsi_register_transport); 2030 2031int iscsi_unregister_transport(struct iscsi_transport *tt) 2032{ 2033 struct iscsi_internal *priv; 2034 unsigned long flags; 2035 2036 BUG_ON(!tt); 2037 2038 mutex_lock(&rx_queue_mutex); 2039 2040 priv = iscsi_if_transport_lookup(tt); 2041 BUG_ON (!priv); 2042 2043 spin_lock_irqsave(&iscsi_transport_lock, flags); 2044 list_del(&priv->list); 2045 spin_unlock_irqrestore(&iscsi_transport_lock, flags); 2046 2047 transport_container_unregister(&priv->conn_cont); 2048 transport_container_unregister(&priv->session_cont); 2049 transport_container_unregister(&priv->t.host_attrs); 2050 2051 sysfs_remove_group(&priv->dev.kobj, &iscsi_transport_group); 2052 device_unregister(&priv->dev); 2053 mutex_unlock(&rx_queue_mutex); 2054 2055 return 0; 2056} 2057EXPORT_SYMBOL_GPL(iscsi_unregister_transport); 2058 2059static __init int iscsi_transport_init(void) 2060{ 2061 int err; 2062 2063 printk(KERN_INFO "Loading iSCSI transport class v%s.\n", 2064 ISCSI_TRANSPORT_VERSION); 2065 2066 atomic_set(&iscsi_session_nr, 0); 2067 2068 err = class_register(&iscsi_transport_class); 2069 if (err) 2070 return err; 2071 2072 err = class_register(&iscsi_endpoint_class); 2073 if (err) 2074 goto unregister_transport_class; 2075 2076 err = transport_class_register(&iscsi_host_class); 2077 if (err) 2078 goto unregister_endpoint_class; 2079 2080 err = transport_class_register(&iscsi_connection_class); 2081 if (err) 2082 goto unregister_host_class; 2083 2084 err = transport_class_register(&iscsi_session_class); 2085 if (err) 2086 goto unregister_conn_class; 2087 2088 nls = netlink_kernel_create(&init_net, NETLINK_ISCSI, 1, iscsi_if_rx, 2089 NULL, THIS_MODULE); 2090 if (!nls) { 2091 err = -ENOBUFS; 2092 goto unregister_session_class; 2093 } 2094 2095 iscsi_eh_timer_workq = create_singlethread_workqueue("iscsi_eh"); 2096 if (!iscsi_eh_timer_workq) 2097 goto release_nls; 2098 2099 return 0; 2100 2101release_nls: 2102 netlink_kernel_release(nls); 2103unregister_session_class: 2104 transport_class_unregister(&iscsi_session_class); 2105unregister_conn_class: 2106 transport_class_unregister(&iscsi_connection_class); 2107unregister_host_class: 2108 transport_class_unregister(&iscsi_host_class); 2109unregister_endpoint_class: 2110 class_unregister(&iscsi_endpoint_class); 2111unregister_transport_class: 2112 class_unregister(&iscsi_transport_class); 2113 return err; 2114} 2115 2116static void __exit iscsi_transport_exit(void) 2117{ 2118 destroy_workqueue(iscsi_eh_timer_workq); 2119 netlink_kernel_release(nls); 2120 transport_class_unregister(&iscsi_connection_class); 2121 transport_class_unregister(&iscsi_session_class); 2122 transport_class_unregister(&iscsi_host_class); 2123 class_unregister(&iscsi_endpoint_class); 2124 class_unregister(&iscsi_transport_class); 2125} 2126 2127module_init(iscsi_transport_init); 2128module_exit(iscsi_transport_exit); 2129 2130MODULE_AUTHOR("Mike Christie <michaelc@cs.wisc.edu>, " 2131 "Dmitry Yusupov <dmitry_yus@yahoo.com>, " 2132 "Alex Aizman <itn780@yahoo.com>"); 2133MODULE_DESCRIPTION("iSCSI Transport Interface"); 2134MODULE_LICENSE("GPL"); 2135MODULE_VERSION(ISCSI_TRANSPORT_VERSION);