1 /* 2 * bnx2i_iscsi.c: Broadcom NetXtreme II iSCSI driver. 3 * 4 * Copyright (c) 2006 - 2009 Broadcom Corporation 5 * Copyright (c) 2007, 2008 Red Hat, Inc. All rights reserved. 6 * Copyright (c) 2007, 2008 Mike Christie 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation. 11 * 12 * Written by: Anil Veerabhadrappa (anilgv@broadcom.com) 13 */ 14 15 #include <scsi/scsi_tcq.h> 16 #include <scsi/libiscsi.h> 17 #include "bnx2i.h" 18 19 struct scsi_transport_template *bnx2i_scsi_xport_template; 20 struct iscsi_transport bnx2i_iscsi_transport; 21 static struct scsi_host_template bnx2i_host_template; 22 23 /* 24 * Global endpoint resource info 25 */ 26 static DEFINE_SPINLOCK(bnx2i_resc_lock); /* protects global resources */ 27 28 29 static int bnx2i_adapter_ready(struct bnx2i_hba *hba) 30 { 31 int retval = 0; 32 33 if (!hba || !test_bit(ADAPTER_STATE_UP, &hba->adapter_state) || 34 test_bit(ADAPTER_STATE_GOING_DOWN, &hba->adapter_state) || 35 test_bit(ADAPTER_STATE_LINK_DOWN, &hba->adapter_state)) 36 retval = -EPERM; 37 return retval; 38 } 39 40 /** 41 * bnx2i_get_write_cmd_bd_idx - identifies various BD bookmarks 42 * @cmd: iscsi cmd struct pointer 43 * @buf_off: absolute buffer offset 44 * @start_bd_off: u32 pointer to return the offset within the BD 45 * indicated by 'start_bd_idx' on which 'buf_off' falls 46 * @start_bd_idx: index of the BD on which 'buf_off' falls 47 * 48 * identifies & marks various bd info for scsi command's imm data, 49 * unsolicited data and the first solicited data seq. 50 */ 51 static void bnx2i_get_write_cmd_bd_idx(struct bnx2i_cmd *cmd, u32 buf_off, 52 u32 *start_bd_off, u32 *start_bd_idx) 53 { 54 struct iscsi_bd *bd_tbl = cmd->io_tbl.bd_tbl; 55 u32 cur_offset = 0; 56 u32 cur_bd_idx = 0; 57 58 if (buf_off) { 59 while (buf_off >= (cur_offset + bd_tbl->buffer_length)) { 60 cur_offset += bd_tbl->buffer_length; 61 cur_bd_idx++; 62 bd_tbl++; 63 } 64 } 65 66 *start_bd_off = buf_off - cur_offset; 67 *start_bd_idx = cur_bd_idx; 68 } 69 70 /** 71 * bnx2i_setup_write_cmd_bd_info - sets up BD various information 72 * @task: transport layer's cmd struct pointer 73 * 74 * identifies & marks various bd info for scsi command's immediate data, 75 * unsolicited data and first solicited data seq which includes BD start 76 * index & BD buf off. his function takes into account iscsi parameter such 77 * as immediate data and unsolicited data is support on this connection. 78 */ 79 static void bnx2i_setup_write_cmd_bd_info(struct iscsi_task *task) 80 { 81 struct bnx2i_cmd *cmd = task->dd_data; 82 u32 start_bd_offset; 83 u32 start_bd_idx; 84 u32 buffer_offset = 0; 85 u32 cmd_len = cmd->req.total_data_transfer_length; 86 87 /* if ImmediateData is turned off & IntialR2T is turned on, 88 * there will be no immediate or unsolicited data, just return. 89 */ 90 if (!iscsi_task_has_unsol_data(task) && !task->imm_count) 91 return; 92 93 /* Immediate data */ 94 buffer_offset += task->imm_count; 95 if (task->imm_count == cmd_len) 96 return; 97 98 if (iscsi_task_has_unsol_data(task)) { 99 bnx2i_get_write_cmd_bd_idx(cmd, buffer_offset, 100 &start_bd_offset, &start_bd_idx); 101 cmd->req.ud_buffer_offset = start_bd_offset; 102 cmd->req.ud_start_bd_index = start_bd_idx; 103 buffer_offset += task->unsol_r2t.data_length; 104 } 105 106 if (buffer_offset != cmd_len) { 107 bnx2i_get_write_cmd_bd_idx(cmd, buffer_offset, 108 &start_bd_offset, &start_bd_idx); 109 if ((start_bd_offset > task->conn->session->first_burst) || 110 (start_bd_idx > scsi_sg_count(cmd->scsi_cmd))) { 111 int i = 0; 112 113 iscsi_conn_printk(KERN_ALERT, task->conn, 114 "bnx2i- error, buf offset 0x%x " 115 "bd_valid %d use_sg %d\n", 116 buffer_offset, cmd->io_tbl.bd_valid, 117 scsi_sg_count(cmd->scsi_cmd)); 118 for (i = 0; i < cmd->io_tbl.bd_valid; i++) 119 iscsi_conn_printk(KERN_ALERT, task->conn, 120 "bnx2i err, bd[%d]: len %x\n", 121 i, cmd->io_tbl.bd_tbl[i].\ 122 buffer_length); 123 } 124 cmd->req.sd_buffer_offset = start_bd_offset; 125 cmd->req.sd_start_bd_index = start_bd_idx; 126 } 127 } 128 129 130 131 /** 132 * bnx2i_map_scsi_sg - maps IO buffer and prepares the BD table 133 * @hba: adapter instance 134 * @cmd: iscsi cmd struct pointer 135 * 136 * map SG list 137 */ 138 static int bnx2i_map_scsi_sg(struct bnx2i_hba *hba, struct bnx2i_cmd *cmd) 139 { 140 struct scsi_cmnd *sc = cmd->scsi_cmd; 141 struct iscsi_bd *bd = cmd->io_tbl.bd_tbl; 142 struct scatterlist *sg; 143 int byte_count = 0; 144 int bd_count = 0; 145 int sg_count; 146 int sg_len; 147 u64 addr; 148 int i; 149 150 BUG_ON(scsi_sg_count(sc) > ISCSI_MAX_BDS_PER_CMD); 151 152 sg_count = scsi_dma_map(sc); 153 154 scsi_for_each_sg(sc, sg, sg_count, i) { 155 sg_len = sg_dma_len(sg); 156 addr = (u64) sg_dma_address(sg); 157 bd[bd_count].buffer_addr_lo = addr & 0xffffffff; 158 bd[bd_count].buffer_addr_hi = addr >> 32; 159 bd[bd_count].buffer_length = sg_len; 160 bd[bd_count].flags = 0; 161 if (bd_count == 0) 162 bd[bd_count].flags = ISCSI_BD_FIRST_IN_BD_CHAIN; 163 164 byte_count += sg_len; 165 bd_count++; 166 } 167 168 if (bd_count) 169 bd[bd_count - 1].flags |= ISCSI_BD_LAST_IN_BD_CHAIN; 170 171 BUG_ON(byte_count != scsi_bufflen(sc)); 172 return bd_count; 173 } 174 175 /** 176 * bnx2i_iscsi_map_sg_list - maps SG list 177 * @cmd: iscsi cmd struct pointer 178 * 179 * creates BD list table for the command 180 */ 181 static void bnx2i_iscsi_map_sg_list(struct bnx2i_cmd *cmd) 182 { 183 int bd_count; 184 185 bd_count = bnx2i_map_scsi_sg(cmd->conn->hba, cmd); 186 if (!bd_count) { 187 struct iscsi_bd *bd = cmd->io_tbl.bd_tbl; 188 189 bd[0].buffer_addr_lo = bd[0].buffer_addr_hi = 0; 190 bd[0].buffer_length = bd[0].flags = 0; 191 } 192 cmd->io_tbl.bd_valid = bd_count; 193 } 194 195 196 /** 197 * bnx2i_iscsi_unmap_sg_list - unmaps SG list 198 * @cmd: iscsi cmd struct pointer 199 * 200 * unmap IO buffers and invalidate the BD table 201 */ 202 void bnx2i_iscsi_unmap_sg_list(struct bnx2i_cmd *cmd) 203 { 204 struct scsi_cmnd *sc = cmd->scsi_cmd; 205 206 if (cmd->io_tbl.bd_valid && sc) { 207 scsi_dma_unmap(sc); 208 cmd->io_tbl.bd_valid = 0; 209 } 210 } 211 212 static void bnx2i_setup_cmd_wqe_template(struct bnx2i_cmd *cmd) 213 { 214 memset(&cmd->req, 0x00, sizeof(cmd->req)); 215 cmd->req.op_code = 0xFF; 216 cmd->req.bd_list_addr_lo = (u32) cmd->io_tbl.bd_tbl_dma; 217 cmd->req.bd_list_addr_hi = 218 (u32) ((u64) cmd->io_tbl.bd_tbl_dma >> 32); 219 220 } 221 222 223 /** 224 * bnx2i_bind_conn_to_iscsi_cid - bind conn structure to 'iscsi_cid' 225 * @hba: pointer to adapter instance 226 * @conn: pointer to iscsi connection 227 * @iscsi_cid: iscsi context ID, range 0 - (MAX_CONN - 1) 228 * 229 * update iscsi cid table entry with connection pointer. This enables 230 * driver to quickly get hold of connection structure pointer in 231 * completion/interrupt thread using iscsi context ID 232 */ 233 static int bnx2i_bind_conn_to_iscsi_cid(struct bnx2i_hba *hba, 234 struct bnx2i_conn *bnx2i_conn, 235 u32 iscsi_cid) 236 { 237 if (hba && hba->cid_que.conn_cid_tbl[iscsi_cid]) { 238 iscsi_conn_printk(KERN_ALERT, bnx2i_conn->cls_conn->dd_data, 239 "conn bind - entry #%d not free\n", iscsi_cid); 240 return -EBUSY; 241 } 242 243 hba->cid_que.conn_cid_tbl[iscsi_cid] = bnx2i_conn; 244 return 0; 245 } 246 247 248 /** 249 * bnx2i_get_conn_from_id - maps an iscsi cid to corresponding conn ptr 250 * @hba: pointer to adapter instance 251 * @iscsi_cid: iscsi context ID, range 0 - (MAX_CONN - 1) 252 */ 253 struct bnx2i_conn *bnx2i_get_conn_from_id(struct bnx2i_hba *hba, 254 u16 iscsi_cid) 255 { 256 if (!hba->cid_que.conn_cid_tbl) { 257 printk(KERN_ERR "bnx2i: ERROR - missing conn<->cid table\n"); 258 return NULL; 259 260 } else if (iscsi_cid >= hba->max_active_conns) { 261 printk(KERN_ERR "bnx2i: wrong cid #%d\n", iscsi_cid); 262 return NULL; 263 } 264 return hba->cid_que.conn_cid_tbl[iscsi_cid]; 265 } 266 267 268 /** 269 * bnx2i_alloc_iscsi_cid - allocates a iscsi_cid from free pool 270 * @hba: pointer to adapter instance 271 */ 272 static u32 bnx2i_alloc_iscsi_cid(struct bnx2i_hba *hba) 273 { 274 int idx; 275 276 if (!hba->cid_que.cid_free_cnt) 277 return -1; 278 279 idx = hba->cid_que.cid_q_cons_idx; 280 hba->cid_que.cid_q_cons_idx++; 281 if (hba->cid_que.cid_q_cons_idx == hba->cid_que.cid_q_max_idx) 282 hba->cid_que.cid_q_cons_idx = 0; 283 284 hba->cid_que.cid_free_cnt--; 285 return hba->cid_que.cid_que[idx]; 286 } 287 288 289 /** 290 * bnx2i_free_iscsi_cid - returns tcp port to free list 291 * @hba: pointer to adapter instance 292 * @iscsi_cid: iscsi context ID to free 293 */ 294 static void bnx2i_free_iscsi_cid(struct bnx2i_hba *hba, u16 iscsi_cid) 295 { 296 int idx; 297 298 if (iscsi_cid == (u16) -1) 299 return; 300 301 hba->cid_que.cid_free_cnt++; 302 303 idx = hba->cid_que.cid_q_prod_idx; 304 hba->cid_que.cid_que[idx] = iscsi_cid; 305 hba->cid_que.conn_cid_tbl[iscsi_cid] = NULL; 306 hba->cid_que.cid_q_prod_idx++; 307 if (hba->cid_que.cid_q_prod_idx == hba->cid_que.cid_q_max_idx) 308 hba->cid_que.cid_q_prod_idx = 0; 309 } 310 311 312 /** 313 * bnx2i_setup_free_cid_que - sets up free iscsi cid queue 314 * @hba: pointer to adapter instance 315 * 316 * allocates memory for iscsi cid queue & 'cid - conn ptr' mapping table, 317 * and initialize table attributes 318 */ 319 static int bnx2i_setup_free_cid_que(struct bnx2i_hba *hba) 320 { 321 int mem_size; 322 int i; 323 324 mem_size = hba->max_active_conns * sizeof(u32); 325 mem_size = (mem_size + (PAGE_SIZE - 1)) & PAGE_MASK; 326 327 hba->cid_que.cid_que_base = kmalloc(mem_size, GFP_KERNEL); 328 if (!hba->cid_que.cid_que_base) 329 return -ENOMEM; 330 331 mem_size = hba->max_active_conns * sizeof(struct bnx2i_conn *); 332 mem_size = (mem_size + (PAGE_SIZE - 1)) & PAGE_MASK; 333 hba->cid_que.conn_cid_tbl = kmalloc(mem_size, GFP_KERNEL); 334 if (!hba->cid_que.conn_cid_tbl) { 335 kfree(hba->cid_que.cid_que_base); 336 hba->cid_que.cid_que_base = NULL; 337 return -ENOMEM; 338 } 339 340 hba->cid_que.cid_que = (u32 *)hba->cid_que.cid_que_base; 341 hba->cid_que.cid_q_prod_idx = 0; 342 hba->cid_que.cid_q_cons_idx = 0; 343 hba->cid_que.cid_q_max_idx = hba->max_active_conns; 344 hba->cid_que.cid_free_cnt = hba->max_active_conns; 345 346 for (i = 0; i < hba->max_active_conns; i++) { 347 hba->cid_que.cid_que[i] = i; 348 hba->cid_que.conn_cid_tbl[i] = NULL; 349 } 350 return 0; 351 } 352 353 354 /** 355 * bnx2i_release_free_cid_que - releases 'iscsi_cid' queue resources 356 * @hba: pointer to adapter instance 357 */ 358 static void bnx2i_release_free_cid_que(struct bnx2i_hba *hba) 359 { 360 kfree(hba->cid_que.cid_que_base); 361 hba->cid_que.cid_que_base = NULL; 362 363 kfree(hba->cid_que.conn_cid_tbl); 364 hba->cid_que.conn_cid_tbl = NULL; 365 } 366 367 368 /** 369 * bnx2i_alloc_ep - allocates ep structure from global pool 370 * @hba: pointer to adapter instance 371 * 372 * routine allocates a free endpoint structure from global pool and 373 * a tcp port to be used for this connection. Global resource lock, 374 * 'bnx2i_resc_lock' is held while accessing shared global data structures 375 */ 376 static struct iscsi_endpoint *bnx2i_alloc_ep(struct bnx2i_hba *hba) 377 { 378 struct iscsi_endpoint *ep; 379 struct bnx2i_endpoint *bnx2i_ep; 380 381 ep = iscsi_create_endpoint(sizeof(*bnx2i_ep)); 382 if (!ep) { 383 printk(KERN_ERR "bnx2i: Could not allocate ep\n"); 384 return NULL; 385 } 386 387 bnx2i_ep = ep->dd_data; 388 INIT_LIST_HEAD(&bnx2i_ep->link); 389 bnx2i_ep->state = EP_STATE_IDLE; 390 bnx2i_ep->ep_iscsi_cid = (u16) -1; 391 bnx2i_ep->hba = hba; 392 bnx2i_ep->hba_age = hba->age; 393 hba->ofld_conns_active++; 394 init_waitqueue_head(&bnx2i_ep->ofld_wait); 395 return ep; 396 } 397 398 399 /** 400 * bnx2i_free_ep - free endpoint 401 * @ep: pointer to iscsi endpoint structure 402 */ 403 static void bnx2i_free_ep(struct iscsi_endpoint *ep) 404 { 405 struct bnx2i_endpoint *bnx2i_ep = ep->dd_data; 406 unsigned long flags; 407 408 spin_lock_irqsave(&bnx2i_resc_lock, flags); 409 bnx2i_ep->state = EP_STATE_IDLE; 410 bnx2i_ep->hba->ofld_conns_active--; 411 412 bnx2i_free_iscsi_cid(bnx2i_ep->hba, bnx2i_ep->ep_iscsi_cid); 413 if (bnx2i_ep->conn) { 414 bnx2i_ep->conn->ep = NULL; 415 bnx2i_ep->conn = NULL; 416 } 417 418 bnx2i_ep->hba = NULL; 419 spin_unlock_irqrestore(&bnx2i_resc_lock, flags); 420 iscsi_destroy_endpoint(ep); 421 } 422 423 424 /** 425 * bnx2i_alloc_bdt - allocates buffer descriptor (BD) table for the command 426 * @hba: adapter instance pointer 427 * @session: iscsi session pointer 428 * @cmd: iscsi command structure 429 */ 430 static int bnx2i_alloc_bdt(struct bnx2i_hba *hba, struct iscsi_session *session, 431 struct bnx2i_cmd *cmd) 432 { 433 struct io_bdt *io = &cmd->io_tbl; 434 struct iscsi_bd *bd; 435 436 io->bd_tbl = dma_alloc_coherent(&hba->pcidev->dev, 437 ISCSI_MAX_BDS_PER_CMD * sizeof(*bd), 438 &io->bd_tbl_dma, GFP_KERNEL); 439 if (!io->bd_tbl) { 440 iscsi_session_printk(KERN_ERR, session, "Could not " 441 "allocate bdt.\n"); 442 return -ENOMEM; 443 } 444 io->bd_valid = 0; 445 return 0; 446 } 447 448 /** 449 * bnx2i_destroy_cmd_pool - destroys iscsi command pool and release BD table 450 * @hba: adapter instance pointer 451 * @session: iscsi session pointer 452 * @cmd: iscsi command structure 453 */ 454 static void bnx2i_destroy_cmd_pool(struct bnx2i_hba *hba, 455 struct iscsi_session *session) 456 { 457 int i; 458 459 for (i = 0; i < session->cmds_max; i++) { 460 struct iscsi_task *task = session->cmds[i]; 461 struct bnx2i_cmd *cmd = task->dd_data; 462 463 if (cmd->io_tbl.bd_tbl) 464 dma_free_coherent(&hba->pcidev->dev, 465 ISCSI_MAX_BDS_PER_CMD * 466 sizeof(struct iscsi_bd), 467 cmd->io_tbl.bd_tbl, 468 cmd->io_tbl.bd_tbl_dma); 469 } 470 471 } 472 473 474 /** 475 * bnx2i_setup_cmd_pool - sets up iscsi command pool for the session 476 * @hba: adapter instance pointer 477 * @session: iscsi session pointer 478 */ 479 static int bnx2i_setup_cmd_pool(struct bnx2i_hba *hba, 480 struct iscsi_session *session) 481 { 482 int i; 483 484 for (i = 0; i < session->cmds_max; i++) { 485 struct iscsi_task *task = session->cmds[i]; 486 struct bnx2i_cmd *cmd = task->dd_data; 487 488 task->hdr = &cmd->hdr; 489 task->hdr_max = sizeof(struct iscsi_hdr); 490 491 if (bnx2i_alloc_bdt(hba, session, cmd)) 492 goto free_bdts; 493 } 494 495 return 0; 496 497 free_bdts: 498 bnx2i_destroy_cmd_pool(hba, session); 499 return -ENOMEM; 500 } 501 502 503 /** 504 * bnx2i_setup_mp_bdt - allocate BD table resources 505 * @hba: pointer to adapter structure 506 * 507 * Allocate memory for dummy buffer and associated BD 508 * table to be used by middle path (MP) requests 509 */ 510 static int bnx2i_setup_mp_bdt(struct bnx2i_hba *hba) 511 { 512 int rc = 0; 513 struct iscsi_bd *mp_bdt; 514 u64 addr; 515 516 hba->mp_bd_tbl = dma_alloc_coherent(&hba->pcidev->dev, PAGE_SIZE, 517 &hba->mp_bd_dma, GFP_KERNEL); 518 if (!hba->mp_bd_tbl) { 519 printk(KERN_ERR "unable to allocate Middle Path BDT\n"); 520 rc = -1; 521 goto out; 522 } 523 524 hba->dummy_buffer = dma_alloc_coherent(&hba->pcidev->dev, PAGE_SIZE, 525 &hba->dummy_buf_dma, GFP_KERNEL); 526 if (!hba->dummy_buffer) { 527 printk(KERN_ERR "unable to alloc Middle Path Dummy Buffer\n"); 528 dma_free_coherent(&hba->pcidev->dev, PAGE_SIZE, 529 hba->mp_bd_tbl, hba->mp_bd_dma); 530 hba->mp_bd_tbl = NULL; 531 rc = -1; 532 goto out; 533 } 534 535 mp_bdt = (struct iscsi_bd *) hba->mp_bd_tbl; 536 addr = (unsigned long) hba->dummy_buf_dma; 537 mp_bdt->buffer_addr_lo = addr & 0xffffffff; 538 mp_bdt->buffer_addr_hi = addr >> 32; 539 mp_bdt->buffer_length = PAGE_SIZE; 540 mp_bdt->flags = ISCSI_BD_LAST_IN_BD_CHAIN | 541 ISCSI_BD_FIRST_IN_BD_CHAIN; 542 out: 543 return rc; 544 } 545 546 547 /** 548 * bnx2i_free_mp_bdt - releases ITT back to free pool 549 * @hba: pointer to adapter instance 550 * 551 * free MP dummy buffer and associated BD table 552 */ 553 static void bnx2i_free_mp_bdt(struct bnx2i_hba *hba) 554 { 555 if (hba->mp_bd_tbl) { 556 dma_free_coherent(&hba->pcidev->dev, PAGE_SIZE, 557 hba->mp_bd_tbl, hba->mp_bd_dma); 558 hba->mp_bd_tbl = NULL; 559 } 560 if (hba->dummy_buffer) { 561 dma_free_coherent(&hba->pcidev->dev, PAGE_SIZE, 562 hba->dummy_buffer, hba->dummy_buf_dma); 563 hba->dummy_buffer = NULL; 564 } 565 return; 566 } 567 568 /** 569 * bnx2i_drop_session - notifies iscsid of connection error. 570 * @hba: adapter instance pointer 571 * @session: iscsi session pointer 572 * 573 * This notifies iscsid that there is a error, so it can initiate 574 * recovery. 575 * 576 * This relies on caller using the iscsi class iterator so the object 577 * is refcounted and does not disapper from under us. 578 */ 579 void bnx2i_drop_session(struct iscsi_cls_session *cls_session) 580 { 581 iscsi_session_failure(cls_session->dd_data, ISCSI_ERR_CONN_FAILED); 582 } 583 584 /** 585 * bnx2i_ep_destroy_list_add - add an entry to EP destroy list 586 * @hba: pointer to adapter instance 587 * @ep: pointer to endpoint (transport indentifier) structure 588 * 589 * EP destroy queue manager 590 */ 591 static int bnx2i_ep_destroy_list_add(struct bnx2i_hba *hba, 592 struct bnx2i_endpoint *ep) 593 { 594 write_lock_bh(&hba->ep_rdwr_lock); 595 list_add_tail(&ep->link, &hba->ep_destroy_list); 596 write_unlock_bh(&hba->ep_rdwr_lock); 597 return 0; 598 } 599 600 /** 601 * bnx2i_ep_destroy_list_del - add an entry to EP destroy list 602 * 603 * @hba: pointer to adapter instance 604 * @ep: pointer to endpoint (transport indentifier) structure 605 * 606 * EP destroy queue manager 607 */ 608 static int bnx2i_ep_destroy_list_del(struct bnx2i_hba *hba, 609 struct bnx2i_endpoint *ep) 610 { 611 write_lock_bh(&hba->ep_rdwr_lock); 612 list_del_init(&ep->link); 613 write_unlock_bh(&hba->ep_rdwr_lock); 614 615 return 0; 616 } 617 618 /** 619 * bnx2i_ep_ofld_list_add - add an entry to ep offload pending list 620 * @hba: pointer to adapter instance 621 * @ep: pointer to endpoint (transport indentifier) structure 622 * 623 * pending conn offload completion queue manager 624 */ 625 static int bnx2i_ep_ofld_list_add(struct bnx2i_hba *hba, 626 struct bnx2i_endpoint *ep) 627 { 628 write_lock_bh(&hba->ep_rdwr_lock); 629 list_add_tail(&ep->link, &hba->ep_ofld_list); 630 write_unlock_bh(&hba->ep_rdwr_lock); 631 return 0; 632 } 633 634 /** 635 * bnx2i_ep_ofld_list_del - add an entry to ep offload pending list 636 * @hba: pointer to adapter instance 637 * @ep: pointer to endpoint (transport indentifier) structure 638 * 639 * pending conn offload completion queue manager 640 */ 641 static int bnx2i_ep_ofld_list_del(struct bnx2i_hba *hba, 642 struct bnx2i_endpoint *ep) 643 { 644 write_lock_bh(&hba->ep_rdwr_lock); 645 list_del_init(&ep->link); 646 write_unlock_bh(&hba->ep_rdwr_lock); 647 return 0; 648 } 649 650 651 /** 652 * bnx2i_find_ep_in_ofld_list - find iscsi_cid in pending list of endpoints 653 * 654 * @hba: pointer to adapter instance 655 * @iscsi_cid: iscsi context ID to find 656 * 657 */ 658 struct bnx2i_endpoint * 659 bnx2i_find_ep_in_ofld_list(struct bnx2i_hba *hba, u32 iscsi_cid) 660 { 661 struct list_head *list; 662 struct list_head *tmp; 663 struct bnx2i_endpoint *ep; 664 665 read_lock_bh(&hba->ep_rdwr_lock); 666 list_for_each_safe(list, tmp, &hba->ep_ofld_list) { 667 ep = (struct bnx2i_endpoint *)list; 668 669 if (ep->ep_iscsi_cid == iscsi_cid) 670 break; 671 ep = NULL; 672 } 673 read_unlock_bh(&hba->ep_rdwr_lock); 674 675 if (!ep) 676 printk(KERN_ERR "l5 cid %d not found\n", iscsi_cid); 677 return ep; 678 } 679 680 681 /** 682 * bnx2i_find_ep_in_destroy_list - find iscsi_cid in destroy list 683 * @hba: pointer to adapter instance 684 * @iscsi_cid: iscsi context ID to find 685 * 686 */ 687 struct bnx2i_endpoint * 688 bnx2i_find_ep_in_destroy_list(struct bnx2i_hba *hba, u32 iscsi_cid) 689 { 690 struct list_head *list; 691 struct list_head *tmp; 692 struct bnx2i_endpoint *ep; 693 694 read_lock_bh(&hba->ep_rdwr_lock); 695 list_for_each_safe(list, tmp, &hba->ep_destroy_list) { 696 ep = (struct bnx2i_endpoint *)list; 697 698 if (ep->ep_iscsi_cid == iscsi_cid) 699 break; 700 ep = NULL; 701 } 702 read_unlock_bh(&hba->ep_rdwr_lock); 703 704 if (!ep) 705 printk(KERN_ERR "l5 cid %d not found\n", iscsi_cid); 706 707 return ep; 708 } 709 710 /** 711 * bnx2i_setup_host_queue_size - assigns shost->can_queue param 712 * @hba: pointer to adapter instance 713 * @shost: scsi host pointer 714 * 715 * Initializes 'can_queue' parameter based on how many outstanding commands 716 * the device can handle. Each device 5708/5709/57710 has different 717 * capabilities 718 */ 719 static void bnx2i_setup_host_queue_size(struct bnx2i_hba *hba, 720 struct Scsi_Host *shost) 721 { 722 if (test_bit(BNX2I_NX2_DEV_5708, &hba->cnic_dev_type)) 723 shost->can_queue = ISCSI_MAX_CMDS_PER_HBA_5708; 724 else if (test_bit(BNX2I_NX2_DEV_5709, &hba->cnic_dev_type)) 725 shost->can_queue = ISCSI_MAX_CMDS_PER_HBA_5709; 726 else if (test_bit(BNX2I_NX2_DEV_57710, &hba->cnic_dev_type)) 727 shost->can_queue = ISCSI_MAX_CMDS_PER_HBA_57710; 728 else 729 shost->can_queue = ISCSI_MAX_CMDS_PER_HBA_5708; 730 } 731 732 733 /** 734 * bnx2i_alloc_hba - allocate and init adapter instance 735 * @cnic: cnic device pointer 736 * 737 * allocate & initialize adapter structure and call other 738 * support routines to do per adapter initialization 739 */ 740 struct bnx2i_hba *bnx2i_alloc_hba(struct cnic_dev *cnic) 741 { 742 struct Scsi_Host *shost; 743 struct bnx2i_hba *hba; 744 745 shost = iscsi_host_alloc(&bnx2i_host_template, sizeof(*hba), 0); 746 if (!shost) 747 return NULL; 748 shost->dma_boundary = cnic->pcidev->dma_mask; 749 shost->transportt = bnx2i_scsi_xport_template; 750 shost->max_id = ISCSI_MAX_CONNS_PER_HBA; 751 shost->max_channel = 0; 752 shost->max_lun = 512; 753 shost->max_cmd_len = 16; 754 755 hba = iscsi_host_priv(shost); 756 hba->shost = shost; 757 hba->netdev = cnic->netdev; 758 /* Get PCI related information and update hba struct members */ 759 hba->pcidev = cnic->pcidev; 760 pci_dev_get(hba->pcidev); 761 hba->pci_did = hba->pcidev->device; 762 hba->pci_vid = hba->pcidev->vendor; 763 hba->pci_sdid = hba->pcidev->subsystem_device; 764 hba->pci_svid = hba->pcidev->subsystem_vendor; 765 hba->pci_func = PCI_FUNC(hba->pcidev->devfn); 766 hba->pci_devno = PCI_SLOT(hba->pcidev->devfn); 767 768 bnx2i_identify_device(hba); 769 bnx2i_setup_host_queue_size(hba, shost); 770 771 if (test_bit(BNX2I_NX2_DEV_5709, &hba->cnic_dev_type)) { 772 hba->regview = ioremap_nocache(hba->netdev->base_addr, 773 BNX2_MQ_CONFIG2); 774 if (!hba->regview) 775 goto ioreg_map_err; 776 } else if (test_bit(BNX2I_NX2_DEV_57710, &hba->cnic_dev_type)) { 777 hba->regview = ioremap_nocache(hba->netdev->base_addr, 4096); 778 if (!hba->regview) 779 goto ioreg_map_err; 780 } 781 782 if (bnx2i_setup_mp_bdt(hba)) 783 goto mp_bdt_mem_err; 784 785 INIT_LIST_HEAD(&hba->ep_ofld_list); 786 INIT_LIST_HEAD(&hba->ep_destroy_list); 787 rwlock_init(&hba->ep_rdwr_lock); 788 789 hba->mtu_supported = BNX2I_MAX_MTU_SUPPORTED; 790 791 /* different values for 5708/5709/57710 */ 792 hba->max_active_conns = ISCSI_MAX_CONNS_PER_HBA; 793 794 if (bnx2i_setup_free_cid_que(hba)) 795 goto cid_que_err; 796 797 /* SQ/RQ/CQ size can be changed via sysfx interface */ 798 if (test_bit(BNX2I_NX2_DEV_57710, &hba->cnic_dev_type)) { 799 if (sq_size && sq_size <= BNX2I_5770X_SQ_WQES_MAX) 800 hba->max_sqes = sq_size; 801 else 802 hba->max_sqes = BNX2I_5770X_SQ_WQES_DEFAULT; 803 } else { /* 5706/5708/5709 */ 804 if (sq_size && sq_size <= BNX2I_570X_SQ_WQES_MAX) 805 hba->max_sqes = sq_size; 806 else 807 hba->max_sqes = BNX2I_570X_SQ_WQES_DEFAULT; 808 } 809 810 hba->max_rqes = rq_size; 811 hba->max_cqes = hba->max_sqes + rq_size; 812 if (test_bit(BNX2I_NX2_DEV_57710, &hba->cnic_dev_type)) { 813 if (hba->max_cqes > BNX2I_5770X_CQ_WQES_MAX) 814 hba->max_cqes = BNX2I_5770X_CQ_WQES_MAX; 815 } else if (hba->max_cqes > BNX2I_570X_CQ_WQES_MAX) 816 hba->max_cqes = BNX2I_570X_CQ_WQES_MAX; 817 818 hba->num_ccell = hba->max_sqes / 2; 819 820 spin_lock_init(&hba->lock); 821 mutex_init(&hba->net_dev_lock); 822 823 if (iscsi_host_add(shost, &hba->pcidev->dev)) 824 goto free_dump_mem; 825 return hba; 826 827 free_dump_mem: 828 bnx2i_release_free_cid_que(hba); 829 cid_que_err: 830 bnx2i_free_mp_bdt(hba); 831 mp_bdt_mem_err: 832 if (hba->regview) { 833 iounmap(hba->regview); 834 hba->regview = NULL; 835 } 836 ioreg_map_err: 837 pci_dev_put(hba->pcidev); 838 scsi_host_put(shost); 839 return NULL; 840 } 841 842 /** 843 * bnx2i_free_hba- releases hba structure and resources held by the adapter 844 * @hba: pointer to adapter instance 845 * 846 * free adapter structure and call various cleanup routines. 847 */ 848 void bnx2i_free_hba(struct bnx2i_hba *hba) 849 { 850 struct Scsi_Host *shost = hba->shost; 851 852 iscsi_host_remove(shost); 853 INIT_LIST_HEAD(&hba->ep_ofld_list); 854 INIT_LIST_HEAD(&hba->ep_destroy_list); 855 pci_dev_put(hba->pcidev); 856 857 if (hba->regview) { 858 iounmap(hba->regview); 859 hba->regview = NULL; 860 } 861 bnx2i_free_mp_bdt(hba); 862 bnx2i_release_free_cid_que(hba); 863 iscsi_host_free(shost); 864 } 865 866 /** 867 * bnx2i_conn_free_login_resources - free DMA resources used for login process 868 * @hba: pointer to adapter instance 869 * @bnx2i_conn: iscsi connection pointer 870 * 871 * Login related resources, mostly BDT & payload DMA memory is freed 872 */ 873 static void bnx2i_conn_free_login_resources(struct bnx2i_hba *hba, 874 struct bnx2i_conn *bnx2i_conn) 875 { 876 if (bnx2i_conn->gen_pdu.resp_bd_tbl) { 877 dma_free_coherent(&hba->pcidev->dev, PAGE_SIZE, 878 bnx2i_conn->gen_pdu.resp_bd_tbl, 879 bnx2i_conn->gen_pdu.resp_bd_dma); 880 bnx2i_conn->gen_pdu.resp_bd_tbl = NULL; 881 } 882 883 if (bnx2i_conn->gen_pdu.req_bd_tbl) { 884 dma_free_coherent(&hba->pcidev->dev, PAGE_SIZE, 885 bnx2i_conn->gen_pdu.req_bd_tbl, 886 bnx2i_conn->gen_pdu.req_bd_dma); 887 bnx2i_conn->gen_pdu.req_bd_tbl = NULL; 888 } 889 890 if (bnx2i_conn->gen_pdu.resp_buf) { 891 dma_free_coherent(&hba->pcidev->dev, 892 ISCSI_DEF_MAX_RECV_SEG_LEN, 893 bnx2i_conn->gen_pdu.resp_buf, 894 bnx2i_conn->gen_pdu.resp_dma_addr); 895 bnx2i_conn->gen_pdu.resp_buf = NULL; 896 } 897 898 if (bnx2i_conn->gen_pdu.req_buf) { 899 dma_free_coherent(&hba->pcidev->dev, 900 ISCSI_DEF_MAX_RECV_SEG_LEN, 901 bnx2i_conn->gen_pdu.req_buf, 902 bnx2i_conn->gen_pdu.req_dma_addr); 903 bnx2i_conn->gen_pdu.req_buf = NULL; 904 } 905 } 906 907 /** 908 * bnx2i_conn_alloc_login_resources - alloc DMA resources for login/nop. 909 * @hba: pointer to adapter instance 910 * @bnx2i_conn: iscsi connection pointer 911 * 912 * Mgmt task DNA resources are allocated in this routine. 913 */ 914 static int bnx2i_conn_alloc_login_resources(struct bnx2i_hba *hba, 915 struct bnx2i_conn *bnx2i_conn) 916 { 917 /* Allocate memory for login request/response buffers */ 918 bnx2i_conn->gen_pdu.req_buf = 919 dma_alloc_coherent(&hba->pcidev->dev, 920 ISCSI_DEF_MAX_RECV_SEG_LEN, 921 &bnx2i_conn->gen_pdu.req_dma_addr, 922 GFP_KERNEL); 923 if (bnx2i_conn->gen_pdu.req_buf == NULL) 924 goto login_req_buf_failure; 925 926 bnx2i_conn->gen_pdu.req_buf_size = 0; 927 bnx2i_conn->gen_pdu.req_wr_ptr = bnx2i_conn->gen_pdu.req_buf; 928 929 bnx2i_conn->gen_pdu.resp_buf = 930 dma_alloc_coherent(&hba->pcidev->dev, 931 ISCSI_DEF_MAX_RECV_SEG_LEN, 932 &bnx2i_conn->gen_pdu.resp_dma_addr, 933 GFP_KERNEL); 934 if (bnx2i_conn->gen_pdu.resp_buf == NULL) 935 goto login_resp_buf_failure; 936 937 bnx2i_conn->gen_pdu.resp_buf_size = ISCSI_DEF_MAX_RECV_SEG_LEN; 938 bnx2i_conn->gen_pdu.resp_wr_ptr = bnx2i_conn->gen_pdu.resp_buf; 939 940 bnx2i_conn->gen_pdu.req_bd_tbl = 941 dma_alloc_coherent(&hba->pcidev->dev, PAGE_SIZE, 942 &bnx2i_conn->gen_pdu.req_bd_dma, GFP_KERNEL); 943 if (bnx2i_conn->gen_pdu.req_bd_tbl == NULL) 944 goto login_req_bd_tbl_failure; 945 946 bnx2i_conn->gen_pdu.resp_bd_tbl = 947 dma_alloc_coherent(&hba->pcidev->dev, PAGE_SIZE, 948 &bnx2i_conn->gen_pdu.resp_bd_dma, 949 GFP_KERNEL); 950 if (bnx2i_conn->gen_pdu.resp_bd_tbl == NULL) 951 goto login_resp_bd_tbl_failure; 952 953 return 0; 954 955 login_resp_bd_tbl_failure: 956 dma_free_coherent(&hba->pcidev->dev, PAGE_SIZE, 957 bnx2i_conn->gen_pdu.req_bd_tbl, 958 bnx2i_conn->gen_pdu.req_bd_dma); 959 bnx2i_conn->gen_pdu.req_bd_tbl = NULL; 960 961 login_req_bd_tbl_failure: 962 dma_free_coherent(&hba->pcidev->dev, ISCSI_DEF_MAX_RECV_SEG_LEN, 963 bnx2i_conn->gen_pdu.resp_buf, 964 bnx2i_conn->gen_pdu.resp_dma_addr); 965 bnx2i_conn->gen_pdu.resp_buf = NULL; 966 login_resp_buf_failure: 967 dma_free_coherent(&hba->pcidev->dev, ISCSI_DEF_MAX_RECV_SEG_LEN, 968 bnx2i_conn->gen_pdu.req_buf, 969 bnx2i_conn->gen_pdu.req_dma_addr); 970 bnx2i_conn->gen_pdu.req_buf = NULL; 971 login_req_buf_failure: 972 iscsi_conn_printk(KERN_ERR, bnx2i_conn->cls_conn->dd_data, 973 "login resource alloc failed!!\n"); 974 return -ENOMEM; 975 976 } 977 978 979 /** 980 * bnx2i_iscsi_prep_generic_pdu_bd - prepares BD table. 981 * @bnx2i_conn: iscsi connection pointer 982 * 983 * Allocates buffers and BD tables before shipping requests to cnic 984 * for PDUs prepared by 'iscsid' daemon 985 */ 986 static void bnx2i_iscsi_prep_generic_pdu_bd(struct bnx2i_conn *bnx2i_conn) 987 { 988 struct iscsi_bd *bd_tbl; 989 990 bd_tbl = (struct iscsi_bd *) bnx2i_conn->gen_pdu.req_bd_tbl; 991 992 bd_tbl->buffer_addr_hi = 993 (u32) ((u64) bnx2i_conn->gen_pdu.req_dma_addr >> 32); 994 bd_tbl->buffer_addr_lo = (u32) bnx2i_conn->gen_pdu.req_dma_addr; 995 bd_tbl->buffer_length = bnx2i_conn->gen_pdu.req_wr_ptr - 996 bnx2i_conn->gen_pdu.req_buf; 997 bd_tbl->reserved0 = 0; 998 bd_tbl->flags = ISCSI_BD_LAST_IN_BD_CHAIN | 999 ISCSI_BD_FIRST_IN_BD_CHAIN; 1000 1001 bd_tbl = (struct iscsi_bd *) bnx2i_conn->gen_pdu.resp_bd_tbl; 1002 bd_tbl->buffer_addr_hi = (u64) bnx2i_conn->gen_pdu.resp_dma_addr >> 32; 1003 bd_tbl->buffer_addr_lo = (u32) bnx2i_conn->gen_pdu.resp_dma_addr; 1004 bd_tbl->buffer_length = ISCSI_DEF_MAX_RECV_SEG_LEN; 1005 bd_tbl->reserved0 = 0; 1006 bd_tbl->flags = ISCSI_BD_LAST_IN_BD_CHAIN | 1007 ISCSI_BD_FIRST_IN_BD_CHAIN; 1008 } 1009 1010 1011 /** 1012 * bnx2i_iscsi_send_generic_request - called to send mgmt tasks. 1013 * @task: transport layer task pointer 1014 * 1015 * called to transmit PDUs prepared by the 'iscsid' daemon. iSCSI login, 1016 * Nop-out and Logout requests flow through this path. 1017 */ 1018 static int bnx2i_iscsi_send_generic_request(struct iscsi_task *task) 1019 { 1020 struct bnx2i_cmd *cmd = task->dd_data; 1021 struct bnx2i_conn *bnx2i_conn = cmd->conn; 1022 int rc = 0; 1023 char *buf; 1024 int data_len; 1025 1026 bnx2i_iscsi_prep_generic_pdu_bd(bnx2i_conn); 1027 switch (task->hdr->opcode & ISCSI_OPCODE_MASK) { 1028 case ISCSI_OP_LOGIN: 1029 bnx2i_send_iscsi_login(bnx2i_conn, task); 1030 break; 1031 case ISCSI_OP_NOOP_OUT: 1032 data_len = bnx2i_conn->gen_pdu.req_buf_size; 1033 buf = bnx2i_conn->gen_pdu.req_buf; 1034 if (data_len) 1035 rc = bnx2i_send_iscsi_nopout(bnx2i_conn, task, 1036 RESERVED_ITT, 1037 buf, data_len, 1); 1038 else 1039 rc = bnx2i_send_iscsi_nopout(bnx2i_conn, task, 1040 RESERVED_ITT, 1041 NULL, 0, 1); 1042 break; 1043 case ISCSI_OP_LOGOUT: 1044 rc = bnx2i_send_iscsi_logout(bnx2i_conn, task); 1045 break; 1046 case ISCSI_OP_SCSI_TMFUNC: 1047 rc = bnx2i_send_iscsi_tmf(bnx2i_conn, task); 1048 break; 1049 default: 1050 iscsi_conn_printk(KERN_ALERT, bnx2i_conn->cls_conn->dd_data, 1051 "send_gen: unsupported op 0x%x\n", 1052 task->hdr->opcode); 1053 } 1054 return rc; 1055 } 1056 1057 1058 /********************************************************************** 1059 * SCSI-ML Interface 1060 **********************************************************************/ 1061 1062 /** 1063 * bnx2i_cpy_scsi_cdb - copies LUN & CDB fields in required format to sq wqe 1064 * @sc: SCSI-ML command pointer 1065 * @cmd: iscsi cmd pointer 1066 */ 1067 static void bnx2i_cpy_scsi_cdb(struct scsi_cmnd *sc, struct bnx2i_cmd *cmd) 1068 { 1069 u32 dword; 1070 int lpcnt; 1071 u8 *srcp; 1072 u32 *dstp; 1073 u32 scsi_lun[2]; 1074 1075 int_to_scsilun(sc->device->lun, (struct scsi_lun *) scsi_lun); 1076 cmd->req.lun[0] = be32_to_cpu(scsi_lun[0]); 1077 cmd->req.lun[1] = be32_to_cpu(scsi_lun[1]); 1078 1079 lpcnt = cmd->scsi_cmd->cmd_len / sizeof(dword); 1080 srcp = (u8 *) sc->cmnd; 1081 dstp = (u32 *) cmd->req.cdb; 1082 while (lpcnt--) { 1083 memcpy(&dword, (const void *) srcp, 4); 1084 *dstp = cpu_to_be32(dword); 1085 srcp += 4; 1086 dstp++; 1087 } 1088 if (sc->cmd_len & 0x3) { 1089 dword = (u32) srcp[0] | ((u32) srcp[1] << 8); 1090 *dstp = cpu_to_be32(dword); 1091 } 1092 } 1093 1094 static void bnx2i_cleanup_task(struct iscsi_task *task) 1095 { 1096 struct iscsi_conn *conn = task->conn; 1097 struct bnx2i_conn *bnx2i_conn = conn->dd_data; 1098 struct bnx2i_hba *hba = bnx2i_conn->hba; 1099 1100 /* 1101 * mgmt task or cmd was never sent to us to transmit. 1102 */ 1103 if (!task->sc || task->state == ISCSI_TASK_PENDING) 1104 return; 1105 /* 1106 * need to clean-up task context to claim dma buffers 1107 */ 1108 if (task->state == ISCSI_TASK_ABRT_TMF) { 1109 bnx2i_send_cmd_cleanup_req(hba, task->dd_data); 1110 1111 spin_unlock_bh(&conn->session->lock); 1112 wait_for_completion_timeout(&bnx2i_conn->cmd_cleanup_cmpl, 1113 msecs_to_jiffies(ISCSI_CMD_CLEANUP_TIMEOUT)); 1114 spin_lock_bh(&conn->session->lock); 1115 } 1116 bnx2i_iscsi_unmap_sg_list(task->dd_data); 1117 } 1118 1119 /** 1120 * bnx2i_mtask_xmit - transmit mtask to chip for further processing 1121 * @conn: transport layer conn structure pointer 1122 * @task: transport layer command structure pointer 1123 */ 1124 static int 1125 bnx2i_mtask_xmit(struct iscsi_conn *conn, struct iscsi_task *task) 1126 { 1127 struct bnx2i_conn *bnx2i_conn = conn->dd_data; 1128 struct bnx2i_cmd *cmd = task->dd_data; 1129 1130 memset(bnx2i_conn->gen_pdu.req_buf, 0, ISCSI_DEF_MAX_RECV_SEG_LEN); 1131 1132 bnx2i_setup_cmd_wqe_template(cmd); 1133 bnx2i_conn->gen_pdu.req_buf_size = task->data_count; 1134 if (task->data_count) { 1135 memcpy(bnx2i_conn->gen_pdu.req_buf, task->data, 1136 task->data_count); 1137 bnx2i_conn->gen_pdu.req_wr_ptr = 1138 bnx2i_conn->gen_pdu.req_buf + task->data_count; 1139 } 1140 cmd->conn = conn->dd_data; 1141 cmd->scsi_cmd = NULL; 1142 return bnx2i_iscsi_send_generic_request(task); 1143 } 1144 1145 /** 1146 * bnx2i_task_xmit - transmit iscsi command to chip for further processing 1147 * @task: transport layer command structure pointer 1148 * 1149 * maps SG buffers and send request to chip/firmware in the form of SQ WQE 1150 */ 1151 static int bnx2i_task_xmit(struct iscsi_task *task) 1152 { 1153 struct iscsi_conn *conn = task->conn; 1154 struct iscsi_session *session = conn->session; 1155 struct Scsi_Host *shost = iscsi_session_to_shost(session->cls_session); 1156 struct bnx2i_hba *hba = iscsi_host_priv(shost); 1157 struct bnx2i_conn *bnx2i_conn = conn->dd_data; 1158 struct scsi_cmnd *sc = task->sc; 1159 struct bnx2i_cmd *cmd = task->dd_data; 1160 struct iscsi_cmd *hdr = (struct iscsi_cmd *) task->hdr; 1161 1162 /* 1163 * If there is no scsi_cmnd this must be a mgmt task 1164 */ 1165 if (!sc) 1166 return bnx2i_mtask_xmit(conn, task); 1167 1168 bnx2i_setup_cmd_wqe_template(cmd); 1169 cmd->req.op_code = ISCSI_OP_SCSI_CMD; 1170 cmd->conn = bnx2i_conn; 1171 cmd->scsi_cmd = sc; 1172 cmd->req.total_data_transfer_length = scsi_bufflen(sc); 1173 cmd->req.cmd_sn = be32_to_cpu(hdr->cmdsn); 1174 1175 bnx2i_iscsi_map_sg_list(cmd); 1176 bnx2i_cpy_scsi_cdb(sc, cmd); 1177 1178 cmd->req.op_attr = ISCSI_ATTR_SIMPLE; 1179 if (sc->sc_data_direction == DMA_TO_DEVICE) { 1180 cmd->req.op_attr |= ISCSI_CMD_REQUEST_WRITE; 1181 cmd->req.itt = task->itt | 1182 (ISCSI_TASK_TYPE_WRITE << ISCSI_CMD_REQUEST_TYPE_SHIFT); 1183 bnx2i_setup_write_cmd_bd_info(task); 1184 } else { 1185 if (scsi_bufflen(sc)) 1186 cmd->req.op_attr |= ISCSI_CMD_REQUEST_READ; 1187 cmd->req.itt = task->itt | 1188 (ISCSI_TASK_TYPE_READ << ISCSI_CMD_REQUEST_TYPE_SHIFT); 1189 } 1190 1191 cmd->req.num_bds = cmd->io_tbl.bd_valid; 1192 if (!cmd->io_tbl.bd_valid) { 1193 cmd->req.bd_list_addr_lo = (u32) hba->mp_bd_dma; 1194 cmd->req.bd_list_addr_hi = (u32) ((u64) hba->mp_bd_dma >> 32); 1195 cmd->req.num_bds = 1; 1196 } 1197 1198 bnx2i_send_iscsi_scsicmd(bnx2i_conn, cmd); 1199 return 0; 1200 } 1201 1202 /** 1203 * bnx2i_session_create - create a new iscsi session 1204 * @cmds_max: max commands supported 1205 * @qdepth: scsi queue depth to support 1206 * @initial_cmdsn: initial iscsi CMDSN to be used for this session 1207 * 1208 * Creates a new iSCSI session instance on given device. 1209 */ 1210 static struct iscsi_cls_session * 1211 bnx2i_session_create(struct iscsi_endpoint *ep, 1212 uint16_t cmds_max, uint16_t qdepth, 1213 uint32_t initial_cmdsn) 1214 { 1215 struct Scsi_Host *shost; 1216 struct iscsi_cls_session *cls_session; 1217 struct bnx2i_hba *hba; 1218 struct bnx2i_endpoint *bnx2i_ep; 1219 1220 if (!ep) { 1221 printk(KERN_ERR "bnx2i: missing ep.\n"); 1222 return NULL; 1223 } 1224 1225 bnx2i_ep = ep->dd_data; 1226 shost = bnx2i_ep->hba->shost; 1227 hba = iscsi_host_priv(shost); 1228 if (bnx2i_adapter_ready(hba)) 1229 return NULL; 1230 1231 /* 1232 * user can override hw limit as long as it is within 1233 * the min/max. 1234 */ 1235 if (cmds_max > hba->max_sqes) 1236 cmds_max = hba->max_sqes; 1237 else if (cmds_max < BNX2I_SQ_WQES_MIN) 1238 cmds_max = BNX2I_SQ_WQES_MIN; 1239 1240 cls_session = iscsi_session_setup(&bnx2i_iscsi_transport, shost, 1241 cmds_max, 0, sizeof(struct bnx2i_cmd), 1242 initial_cmdsn, ISCSI_MAX_TARGET); 1243 if (!cls_session) 1244 return NULL; 1245 1246 if (bnx2i_setup_cmd_pool(hba, cls_session->dd_data)) 1247 goto session_teardown; 1248 return cls_session; 1249 1250 session_teardown: 1251 iscsi_session_teardown(cls_session); 1252 return NULL; 1253 } 1254 1255 1256 /** 1257 * bnx2i_session_destroy - destroys iscsi session 1258 * @cls_session: pointer to iscsi cls session 1259 * 1260 * Destroys previously created iSCSI session instance and releases 1261 * all resources held by it 1262 */ 1263 static void bnx2i_session_destroy(struct iscsi_cls_session *cls_session) 1264 { 1265 struct iscsi_session *session = cls_session->dd_data; 1266 struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); 1267 struct bnx2i_hba *hba = iscsi_host_priv(shost); 1268 1269 bnx2i_destroy_cmd_pool(hba, session); 1270 iscsi_session_teardown(cls_session); 1271 } 1272 1273 1274 /** 1275 * bnx2i_conn_create - create iscsi connection instance 1276 * @cls_session: pointer to iscsi cls session 1277 * @cid: iscsi cid as per rfc (not NX2's CID terminology) 1278 * 1279 * Creates a new iSCSI connection instance for a given session 1280 */ 1281 static struct iscsi_cls_conn * 1282 bnx2i_conn_create(struct iscsi_cls_session *cls_session, uint32_t cid) 1283 { 1284 struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); 1285 struct bnx2i_hba *hba = iscsi_host_priv(shost); 1286 struct bnx2i_conn *bnx2i_conn; 1287 struct iscsi_cls_conn *cls_conn; 1288 struct iscsi_conn *conn; 1289 1290 cls_conn = iscsi_conn_setup(cls_session, sizeof(*bnx2i_conn), 1291 cid); 1292 if (!cls_conn) 1293 return NULL; 1294 conn = cls_conn->dd_data; 1295 1296 bnx2i_conn = conn->dd_data; 1297 bnx2i_conn->cls_conn = cls_conn; 1298 bnx2i_conn->hba = hba; 1299 /* 'ep' ptr will be assigned in bind() call */ 1300 bnx2i_conn->ep = NULL; 1301 init_completion(&bnx2i_conn->cmd_cleanup_cmpl); 1302 1303 if (bnx2i_conn_alloc_login_resources(hba, bnx2i_conn)) { 1304 iscsi_conn_printk(KERN_ALERT, conn, 1305 "conn_new: login resc alloc failed!!\n"); 1306 goto free_conn; 1307 } 1308 1309 return cls_conn; 1310 1311 free_conn: 1312 iscsi_conn_teardown(cls_conn); 1313 return NULL; 1314 } 1315 1316 /** 1317 * bnx2i_conn_bind - binds iscsi sess, conn and ep objects together 1318 * @cls_session: pointer to iscsi cls session 1319 * @cls_conn: pointer to iscsi cls conn 1320 * @transport_fd: 64-bit EP handle 1321 * @is_leading: leading connection on this session? 1322 * 1323 * Binds together iSCSI session instance, iSCSI connection instance 1324 * and the TCP connection. This routine returns error code if 1325 * TCP connection does not belong on the device iSCSI sess/conn 1326 * is bound 1327 */ 1328 static int bnx2i_conn_bind(struct iscsi_cls_session *cls_session, 1329 struct iscsi_cls_conn *cls_conn, 1330 uint64_t transport_fd, int is_leading) 1331 { 1332 struct iscsi_conn *conn = cls_conn->dd_data; 1333 struct bnx2i_conn *bnx2i_conn = conn->dd_data; 1334 struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); 1335 struct bnx2i_hba *hba = iscsi_host_priv(shost); 1336 struct bnx2i_endpoint *bnx2i_ep; 1337 struct iscsi_endpoint *ep; 1338 int ret_code; 1339 1340 ep = iscsi_lookup_endpoint(transport_fd); 1341 if (!ep) 1342 return -EINVAL; 1343 1344 bnx2i_ep = ep->dd_data; 1345 if ((bnx2i_ep->state == EP_STATE_TCP_FIN_RCVD) || 1346 (bnx2i_ep->state == EP_STATE_TCP_RST_RCVD)) 1347 /* Peer disconnect via' FIN or RST */ 1348 return -EINVAL; 1349 1350 if (iscsi_conn_bind(cls_session, cls_conn, is_leading)) 1351 return -EINVAL; 1352 1353 if (bnx2i_ep->hba != hba) { 1354 /* Error - TCP connection does not belong to this device 1355 */ 1356 iscsi_conn_printk(KERN_ALERT, cls_conn->dd_data, 1357 "conn bind, ep=0x%p (%s) does not", 1358 bnx2i_ep, bnx2i_ep->hba->netdev->name); 1359 iscsi_conn_printk(KERN_ALERT, cls_conn->dd_data, 1360 "belong to hba (%s)\n", 1361 hba->netdev->name); 1362 return -EEXIST; 1363 } 1364 1365 bnx2i_ep->conn = bnx2i_conn; 1366 bnx2i_conn->ep = bnx2i_ep; 1367 bnx2i_conn->iscsi_conn_cid = bnx2i_ep->ep_iscsi_cid; 1368 bnx2i_conn->fw_cid = bnx2i_ep->ep_cid; 1369 1370 ret_code = bnx2i_bind_conn_to_iscsi_cid(hba, bnx2i_conn, 1371 bnx2i_ep->ep_iscsi_cid); 1372 1373 /* 5706/5708/5709 FW takes RQ as full when initiated, but for 57710 1374 * driver needs to explicitly replenish RQ index during setup. 1375 */ 1376 if (test_bit(BNX2I_NX2_DEV_57710, &bnx2i_ep->hba->cnic_dev_type)) 1377 bnx2i_put_rq_buf(bnx2i_conn, 0); 1378 1379 bnx2i_arm_cq_event_coalescing(bnx2i_conn->ep, CNIC_ARM_CQE); 1380 return ret_code; 1381 } 1382 1383 1384 /** 1385 * bnx2i_conn_destroy - destroy iscsi connection instance & release resources 1386 * @cls_conn: pointer to iscsi cls conn 1387 * 1388 * Destroy an iSCSI connection instance and release memory resources held by 1389 * this connection 1390 */ 1391 static void bnx2i_conn_destroy(struct iscsi_cls_conn *cls_conn) 1392 { 1393 struct iscsi_conn *conn = cls_conn->dd_data; 1394 struct bnx2i_conn *bnx2i_conn = conn->dd_data; 1395 struct Scsi_Host *shost; 1396 struct bnx2i_hba *hba; 1397 1398 shost = iscsi_session_to_shost(iscsi_conn_to_session(cls_conn)); 1399 hba = iscsi_host_priv(shost); 1400 1401 bnx2i_conn_free_login_resources(hba, bnx2i_conn); 1402 iscsi_conn_teardown(cls_conn); 1403 } 1404 1405 1406 /** 1407 * bnx2i_conn_get_param - return iscsi connection parameter to caller 1408 * @cls_conn: pointer to iscsi cls conn 1409 * @param: parameter type identifier 1410 * @buf: buffer pointer 1411 * 1412 * returns iSCSI connection parameters 1413 */ 1414 static int bnx2i_conn_get_param(struct iscsi_cls_conn *cls_conn, 1415 enum iscsi_param param, char *buf) 1416 { 1417 struct iscsi_conn *conn = cls_conn->dd_data; 1418 struct bnx2i_conn *bnx2i_conn = conn->dd_data; 1419 int len = 0; 1420 1421 switch (param) { 1422 case ISCSI_PARAM_CONN_PORT: 1423 if (bnx2i_conn->ep) 1424 len = sprintf(buf, "%hu\n", 1425 bnx2i_conn->ep->cm_sk->dst_port); 1426 break; 1427 case ISCSI_PARAM_CONN_ADDRESS: 1428 if (bnx2i_conn->ep) 1429 len = sprintf(buf, NIPQUAD_FMT "\n", 1430 NIPQUAD(bnx2i_conn->ep->cm_sk->dst_ip)); 1431 break; 1432 default: 1433 return iscsi_conn_get_param(cls_conn, param, buf); 1434 } 1435 1436 return len; 1437 } 1438 1439 /** 1440 * bnx2i_host_get_param - returns host (adapter) related parameters 1441 * @shost: scsi host pointer 1442 * @param: parameter type identifier 1443 * @buf: buffer pointer 1444 */ 1445 static int bnx2i_host_get_param(struct Scsi_Host *shost, 1446 enum iscsi_host_param param, char *buf) 1447 { 1448 struct bnx2i_hba *hba = iscsi_host_priv(shost); 1449 int len = 0; 1450 1451 switch (param) { 1452 case ISCSI_HOST_PARAM_HWADDRESS: 1453 len = sysfs_format_mac(buf, hba->cnic->mac_addr, 6); 1454 break; 1455 case ISCSI_HOST_PARAM_NETDEV_NAME: 1456 len = sprintf(buf, "%s\n", hba->netdev->name); 1457 break; 1458 default: 1459 return iscsi_host_get_param(shost, param, buf); 1460 } 1461 return len; 1462 } 1463 1464 /** 1465 * bnx2i_conn_start - completes iscsi connection migration to FFP 1466 * @cls_conn: pointer to iscsi cls conn 1467 * 1468 * last call in FFP migration to handover iscsi conn to the driver 1469 */ 1470 static int bnx2i_conn_start(struct iscsi_cls_conn *cls_conn) 1471 { 1472 struct iscsi_conn *conn = cls_conn->dd_data; 1473 struct bnx2i_conn *bnx2i_conn = conn->dd_data; 1474 1475 bnx2i_conn->ep->state = EP_STATE_ULP_UPDATE_START; 1476 bnx2i_update_iscsi_conn(conn); 1477 1478 /* 1479 * this should normally not sleep for a long time so it should 1480 * not disrupt the caller. 1481 */ 1482 bnx2i_conn->ep->ofld_timer.expires = 1 * HZ + jiffies; 1483 bnx2i_conn->ep->ofld_timer.function = bnx2i_ep_ofld_timer; 1484 bnx2i_conn->ep->ofld_timer.data = (unsigned long) bnx2i_conn->ep; 1485 add_timer(&bnx2i_conn->ep->ofld_timer); 1486 /* update iSCSI context for this conn, wait for CNIC to complete */ 1487 wait_event_interruptible(bnx2i_conn->ep->ofld_wait, 1488 bnx2i_conn->ep->state != EP_STATE_ULP_UPDATE_START); 1489 1490 if (signal_pending(current)) 1491 flush_signals(current); 1492 del_timer_sync(&bnx2i_conn->ep->ofld_timer); 1493 1494 iscsi_conn_start(cls_conn); 1495 return 0; 1496 } 1497 1498 1499 /** 1500 * bnx2i_conn_get_stats - returns iSCSI stats 1501 * @cls_conn: pointer to iscsi cls conn 1502 * @stats: pointer to iscsi statistic struct 1503 */ 1504 static void bnx2i_conn_get_stats(struct iscsi_cls_conn *cls_conn, 1505 struct iscsi_stats *stats) 1506 { 1507 struct iscsi_conn *conn = cls_conn->dd_data; 1508 1509 stats->txdata_octets = conn->txdata_octets; 1510 stats->rxdata_octets = conn->rxdata_octets; 1511 stats->scsicmd_pdus = conn->scsicmd_pdus_cnt; 1512 stats->dataout_pdus = conn->dataout_pdus_cnt; 1513 stats->scsirsp_pdus = conn->scsirsp_pdus_cnt; 1514 stats->datain_pdus = conn->datain_pdus_cnt; 1515 stats->r2t_pdus = conn->r2t_pdus_cnt; 1516 stats->tmfcmd_pdus = conn->tmfcmd_pdus_cnt; 1517 stats->tmfrsp_pdus = conn->tmfrsp_pdus_cnt; 1518 stats->custom_length = 3; 1519 strcpy(stats->custom[2].desc, "eh_abort_cnt"); 1520 stats->custom[2].value = conn->eh_abort_cnt; 1521 stats->digest_err = 0; 1522 stats->timeout_err = 0; 1523 stats->custom_length = 0; 1524 } 1525 1526 1527 /** 1528 * bnx2i_check_route - checks if target IP route belongs to one of NX2 devices 1529 * @dst_addr: target IP address 1530 * 1531 * check if route resolves to BNX2 device 1532 */ 1533 static struct bnx2i_hba *bnx2i_check_route(struct sockaddr *dst_addr) 1534 { 1535 struct sockaddr_in *desti = (struct sockaddr_in *) dst_addr; 1536 struct bnx2i_hba *hba; 1537 struct cnic_dev *cnic = NULL; 1538 1539 bnx2i_reg_dev_all(); 1540 1541 hba = get_adapter_list_head(); 1542 if (hba && hba->cnic) 1543 cnic = hba->cnic->cm_select_dev(desti, CNIC_ULP_ISCSI); 1544 if (!cnic) { 1545 printk(KERN_ALERT "bnx2i: no route," 1546 "can't connect using cnic\n"); 1547 goto no_nx2_route; 1548 } 1549 hba = bnx2i_find_hba_for_cnic(cnic); 1550 if (!hba) 1551 goto no_nx2_route; 1552 1553 if (bnx2i_adapter_ready(hba)) { 1554 printk(KERN_ALERT "bnx2i: check route, hba not found\n"); 1555 goto no_nx2_route; 1556 } 1557 if (hba->netdev->mtu > hba->mtu_supported) { 1558 printk(KERN_ALERT "bnx2i: %s network i/f mtu is set to %d\n", 1559 hba->netdev->name, hba->netdev->mtu); 1560 printk(KERN_ALERT "bnx2i: iSCSI HBA can support mtu of %d\n", 1561 hba->mtu_supported); 1562 goto no_nx2_route; 1563 } 1564 return hba; 1565 no_nx2_route: 1566 return NULL; 1567 } 1568 1569 1570 /** 1571 * bnx2i_tear_down_conn - tear down iscsi/tcp connection and free resources 1572 * @hba: pointer to adapter instance 1573 * @ep: endpoint (transport indentifier) structure 1574 * 1575 * destroys cm_sock structure and on chip iscsi context 1576 */ 1577 static int bnx2i_tear_down_conn(struct bnx2i_hba *hba, 1578 struct bnx2i_endpoint *ep) 1579 { 1580 if (test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic)) 1581 hba->cnic->cm_destroy(ep->cm_sk); 1582 1583 if (test_bit(ADAPTER_STATE_GOING_DOWN, &ep->hba->adapter_state)) 1584 ep->state = EP_STATE_DISCONN_COMPL; 1585 1586 if (test_bit(BNX2I_NX2_DEV_57710, &hba->cnic_dev_type) && 1587 ep->state == EP_STATE_DISCONN_TIMEDOUT) { 1588 printk(KERN_ALERT "bnx2i - ERROR - please submit GRC Dump," 1589 " NW/PCIe trace, driver msgs to developers" 1590 " for analysis\n"); 1591 return 1; 1592 } 1593 1594 ep->state = EP_STATE_CLEANUP_START; 1595 init_timer(&ep->ofld_timer); 1596 ep->ofld_timer.expires = 10*HZ + jiffies; 1597 ep->ofld_timer.function = bnx2i_ep_ofld_timer; 1598 ep->ofld_timer.data = (unsigned long) ep; 1599 add_timer(&ep->ofld_timer); 1600 1601 bnx2i_ep_destroy_list_add(hba, ep); 1602 1603 /* destroy iSCSI context, wait for it to complete */ 1604 bnx2i_send_conn_destroy(hba, ep); 1605 wait_event_interruptible(ep->ofld_wait, 1606 (ep->state != EP_STATE_CLEANUP_START)); 1607 1608 if (signal_pending(current)) 1609 flush_signals(current); 1610 del_timer_sync(&ep->ofld_timer); 1611 1612 bnx2i_ep_destroy_list_del(hba, ep); 1613 1614 if (ep->state != EP_STATE_CLEANUP_CMPL) 1615 /* should never happen */ 1616 printk(KERN_ALERT "bnx2i - conn destroy failed\n"); 1617 1618 return 0; 1619 } 1620 1621 1622 /** 1623 * bnx2i_ep_connect - establish TCP connection to target portal 1624 * @shost: scsi host 1625 * @dst_addr: target IP address 1626 * @non_blocking: blocking or non-blocking call 1627 * 1628 * this routine initiates the TCP/IP connection by invoking Option-2 i/f 1629 * with l5_core and the CNIC. This is a multi-step process of resolving 1630 * route to target, create a iscsi connection context, handshaking with 1631 * CNIC module to create/initialize the socket struct and finally 1632 * sending down option-2 request to complete TCP 3-way handshake 1633 */ 1634 static struct iscsi_endpoint *bnx2i_ep_connect(struct Scsi_Host *shost, 1635 struct sockaddr *dst_addr, 1636 int non_blocking) 1637 { 1638 u32 iscsi_cid = BNX2I_CID_RESERVED; 1639 struct sockaddr_in *desti = (struct sockaddr_in *) dst_addr; 1640 struct sockaddr_in6 *desti6; 1641 struct bnx2i_endpoint *bnx2i_ep; 1642 struct bnx2i_hba *hba; 1643 struct cnic_dev *cnic; 1644 struct cnic_sockaddr saddr; 1645 struct iscsi_endpoint *ep; 1646 int rc = 0; 1647 1648 if (shost) { 1649 /* driver is given scsi host to work with */ 1650 hba = iscsi_host_priv(shost); 1651 /* Register the device with cnic if not already done so */ 1652 bnx2i_register_device(hba); 1653 } else 1654 /* 1655 * check if the given destination can be reached through 1656 * a iscsi capable NetXtreme2 device 1657 */ 1658 hba = bnx2i_check_route(dst_addr); 1659 1660 if (!hba) { 1661 rc = -ENOMEM; 1662 goto check_busy; 1663 } 1664 1665 cnic = hba->cnic; 1666 ep = bnx2i_alloc_ep(hba); 1667 if (!ep) { 1668 rc = -ENOMEM; 1669 goto check_busy; 1670 } 1671 bnx2i_ep = ep->dd_data; 1672 1673 mutex_lock(&hba->net_dev_lock); 1674 if (bnx2i_adapter_ready(hba)) { 1675 rc = -EPERM; 1676 goto net_if_down; 1677 } 1678 1679 bnx2i_ep->num_active_cmds = 0; 1680 iscsi_cid = bnx2i_alloc_iscsi_cid(hba); 1681 if (iscsi_cid == -1) { 1682 printk(KERN_ALERT "alloc_ep: unable to allocate iscsi cid\n"); 1683 rc = -ENOMEM; 1684 goto iscsi_cid_err; 1685 } 1686 bnx2i_ep->hba_age = hba->age; 1687 1688 rc = bnx2i_alloc_qp_resc(hba, bnx2i_ep); 1689 if (rc != 0) { 1690 printk(KERN_ALERT "bnx2i: ep_conn, alloc QP resc error\n"); 1691 rc = -ENOMEM; 1692 goto qp_resc_err; 1693 } 1694 1695 bnx2i_ep->ep_iscsi_cid = (u16)iscsi_cid; 1696 bnx2i_ep->state = EP_STATE_OFLD_START; 1697 bnx2i_ep_ofld_list_add(hba, bnx2i_ep); 1698 1699 init_timer(&bnx2i_ep->ofld_timer); 1700 bnx2i_ep->ofld_timer.expires = 2 * HZ + jiffies; 1701 bnx2i_ep->ofld_timer.function = bnx2i_ep_ofld_timer; 1702 bnx2i_ep->ofld_timer.data = (unsigned long) bnx2i_ep; 1703 add_timer(&bnx2i_ep->ofld_timer); 1704 1705 bnx2i_send_conn_ofld_req(hba, bnx2i_ep); 1706 1707 /* Wait for CNIC hardware to setup conn context and return 'cid' */ 1708 wait_event_interruptible(bnx2i_ep->ofld_wait, 1709 bnx2i_ep->state != EP_STATE_OFLD_START); 1710 1711 if (signal_pending(current)) 1712 flush_signals(current); 1713 del_timer_sync(&bnx2i_ep->ofld_timer); 1714 1715 bnx2i_ep_ofld_list_del(hba, bnx2i_ep); 1716 1717 if (bnx2i_ep->state != EP_STATE_OFLD_COMPL) { 1718 rc = -ENOSPC; 1719 goto conn_failed; 1720 } 1721 1722 rc = cnic->cm_create(cnic, CNIC_ULP_ISCSI, bnx2i_ep->ep_cid, 1723 iscsi_cid, &bnx2i_ep->cm_sk, bnx2i_ep); 1724 if (rc) { 1725 rc = -EINVAL; 1726 goto conn_failed; 1727 } 1728 1729 bnx2i_ep->cm_sk->rcv_buf = 256 * 1024; 1730 bnx2i_ep->cm_sk->snd_buf = 256 * 1024; 1731 clear_bit(SK_TCP_TIMESTAMP, &bnx2i_ep->cm_sk->tcp_flags); 1732 1733 memset(&saddr, 0, sizeof(saddr)); 1734 if (dst_addr->sa_family == AF_INET) { 1735 desti = (struct sockaddr_in *) dst_addr; 1736 saddr.remote.v4 = *desti; 1737 saddr.local.v4.sin_family = desti->sin_family; 1738 } else if (dst_addr->sa_family == AF_INET6) { 1739 desti6 = (struct sockaddr_in6 *) dst_addr; 1740 saddr.remote.v6 = *desti6; 1741 saddr.local.v6.sin6_family = desti6->sin6_family; 1742 } 1743 1744 bnx2i_ep->timestamp = jiffies; 1745 bnx2i_ep->state = EP_STATE_CONNECT_START; 1746 if (!test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic)) { 1747 rc = -EINVAL; 1748 goto conn_failed; 1749 } else 1750 rc = cnic->cm_connect(bnx2i_ep->cm_sk, &saddr); 1751 1752 if (rc) 1753 goto release_ep; 1754 1755 if (bnx2i_map_ep_dbell_regs(bnx2i_ep)) 1756 goto release_ep; 1757 mutex_unlock(&hba->net_dev_lock); 1758 return ep; 1759 1760 release_ep: 1761 if (bnx2i_tear_down_conn(hba, bnx2i_ep)) { 1762 mutex_unlock(&hba->net_dev_lock); 1763 return ERR_PTR(rc); 1764 } 1765 conn_failed: 1766 net_if_down: 1767 iscsi_cid_err: 1768 bnx2i_free_qp_resc(hba, bnx2i_ep); 1769 qp_resc_err: 1770 bnx2i_free_ep(ep); 1771 mutex_unlock(&hba->net_dev_lock); 1772 check_busy: 1773 bnx2i_unreg_dev_all(); 1774 return ERR_PTR(rc); 1775 } 1776 1777 1778 /** 1779 * bnx2i_ep_poll - polls for TCP connection establishement 1780 * @ep: TCP connection (endpoint) handle 1781 * @timeout_ms: timeout value in milli secs 1782 * 1783 * polls for TCP connect request to complete 1784 */ 1785 static int bnx2i_ep_poll(struct iscsi_endpoint *ep, int timeout_ms) 1786 { 1787 struct bnx2i_endpoint *bnx2i_ep; 1788 int rc = 0; 1789 1790 bnx2i_ep = ep->dd_data; 1791 if ((bnx2i_ep->state == EP_STATE_IDLE) || 1792 (bnx2i_ep->state == EP_STATE_CONNECT_FAILED) || 1793 (bnx2i_ep->state == EP_STATE_OFLD_FAILED)) 1794 return -1; 1795 if (bnx2i_ep->state == EP_STATE_CONNECT_COMPL) 1796 return 1; 1797 1798 rc = wait_event_interruptible_timeout(bnx2i_ep->ofld_wait, 1799 ((bnx2i_ep->state == 1800 EP_STATE_OFLD_FAILED) || 1801 (bnx2i_ep->state == 1802 EP_STATE_CONNECT_FAILED) || 1803 (bnx2i_ep->state == 1804 EP_STATE_CONNECT_COMPL)), 1805 msecs_to_jiffies(timeout_ms)); 1806 if (!rc || (bnx2i_ep->state == EP_STATE_OFLD_FAILED)) 1807 rc = -1; 1808 1809 if (rc > 0) 1810 return 1; 1811 else if (!rc) 1812 return 0; /* timeout */ 1813 else 1814 return rc; 1815 } 1816 1817 1818 /** 1819 * bnx2i_ep_tcp_conn_active - check EP state transition 1820 * @ep: endpoint pointer 1821 * 1822 * check if underlying TCP connection is active 1823 */ 1824 static int bnx2i_ep_tcp_conn_active(struct bnx2i_endpoint *bnx2i_ep) 1825 { 1826 int ret; 1827 int cnic_dev_10g = 0; 1828 1829 if (test_bit(BNX2I_NX2_DEV_57710, &bnx2i_ep->hba->cnic_dev_type)) 1830 cnic_dev_10g = 1; 1831 1832 switch (bnx2i_ep->state) { 1833 case EP_STATE_CONNECT_START: 1834 case EP_STATE_CLEANUP_FAILED: 1835 case EP_STATE_OFLD_FAILED: 1836 case EP_STATE_DISCONN_TIMEDOUT: 1837 ret = 0; 1838 break; 1839 case EP_STATE_CONNECT_COMPL: 1840 case EP_STATE_ULP_UPDATE_START: 1841 case EP_STATE_ULP_UPDATE_COMPL: 1842 case EP_STATE_TCP_FIN_RCVD: 1843 case EP_STATE_ULP_UPDATE_FAILED: 1844 ret = 1; 1845 break; 1846 case EP_STATE_TCP_RST_RCVD: 1847 ret = 0; 1848 break; 1849 case EP_STATE_CONNECT_FAILED: 1850 if (cnic_dev_10g) 1851 ret = 1; 1852 else 1853 ret = 0; 1854 break; 1855 default: 1856 ret = 0; 1857 } 1858 1859 return ret; 1860 } 1861 1862 1863 /** 1864 * bnx2i_ep_disconnect - executes TCP connection teardown process 1865 * @ep: TCP connection (endpoint) handle 1866 * 1867 * executes TCP connection teardown process 1868 */ 1869 static void bnx2i_ep_disconnect(struct iscsi_endpoint *ep) 1870 { 1871 struct bnx2i_endpoint *bnx2i_ep; 1872 struct bnx2i_conn *bnx2i_conn = NULL; 1873 struct iscsi_session *session = NULL; 1874 struct iscsi_conn *conn; 1875 struct cnic_dev *cnic; 1876 struct bnx2i_hba *hba; 1877 1878 bnx2i_ep = ep->dd_data; 1879 1880 /* driver should not attempt connection cleanup until TCP_CONNECT 1881 * completes either successfully or fails. Timeout is 9-secs, so 1882 * wait for it to complete 1883 */ 1884 while ((bnx2i_ep->state == EP_STATE_CONNECT_START) && 1885 !time_after(jiffies, bnx2i_ep->timestamp + (12 * HZ))) 1886 msleep(250); 1887 1888 if (bnx2i_ep->conn) { 1889 bnx2i_conn = bnx2i_ep->conn; 1890 conn = bnx2i_conn->cls_conn->dd_data; 1891 session = conn->session; 1892 1893 iscsi_suspend_queue(conn); 1894 } 1895 1896 hba = bnx2i_ep->hba; 1897 if (bnx2i_ep->state == EP_STATE_IDLE) 1898 goto return_bnx2i_ep; 1899 cnic = hba->cnic; 1900 1901 mutex_lock(&hba->net_dev_lock); 1902 1903 if (!test_bit(ADAPTER_STATE_UP, &hba->adapter_state)) 1904 goto free_resc; 1905 if (bnx2i_ep->hba_age != hba->age) 1906 goto free_resc; 1907 1908 if (!bnx2i_ep_tcp_conn_active(bnx2i_ep)) 1909 goto destory_conn; 1910 1911 bnx2i_ep->state = EP_STATE_DISCONN_START; 1912 1913 init_timer(&bnx2i_ep->ofld_timer); 1914 bnx2i_ep->ofld_timer.expires = 10*HZ + jiffies; 1915 bnx2i_ep->ofld_timer.function = bnx2i_ep_ofld_timer; 1916 bnx2i_ep->ofld_timer.data = (unsigned long) bnx2i_ep; 1917 add_timer(&bnx2i_ep->ofld_timer); 1918 1919 if (test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic)) { 1920 int close = 0; 1921 1922 if (session) { 1923 spin_lock_bh(&session->lock); 1924 if (session->state == ISCSI_STATE_LOGGING_OUT) 1925 close = 1; 1926 spin_unlock_bh(&session->lock); 1927 } 1928 if (close) 1929 cnic->cm_close(bnx2i_ep->cm_sk); 1930 else 1931 cnic->cm_abort(bnx2i_ep->cm_sk); 1932 } else 1933 goto free_resc; 1934 1935 /* wait for option-2 conn teardown */ 1936 wait_event_interruptible(bnx2i_ep->ofld_wait, 1937 bnx2i_ep->state != EP_STATE_DISCONN_START); 1938 1939 if (signal_pending(current)) 1940 flush_signals(current); 1941 del_timer_sync(&bnx2i_ep->ofld_timer); 1942 1943 destory_conn: 1944 if (bnx2i_tear_down_conn(hba, bnx2i_ep)) { 1945 mutex_unlock(&hba->net_dev_lock); 1946 return; 1947 } 1948 free_resc: 1949 mutex_unlock(&hba->net_dev_lock); 1950 bnx2i_free_qp_resc(hba, bnx2i_ep); 1951 return_bnx2i_ep: 1952 if (bnx2i_conn) 1953 bnx2i_conn->ep = NULL; 1954 1955 bnx2i_free_ep(ep); 1956 1957 if (!hba->ofld_conns_active) 1958 bnx2i_unreg_dev_all(); 1959 } 1960 1961 1962 /** 1963 * bnx2i_nl_set_path - ISCSI_UEVENT_PATH_UPDATE user message handler 1964 * @buf: pointer to buffer containing iscsi path message 1965 * 1966 */ 1967 static int bnx2i_nl_set_path(struct Scsi_Host *shost, struct iscsi_path *params) 1968 { 1969 struct bnx2i_hba *hba = iscsi_host_priv(shost); 1970 char *buf = (char *) params; 1971 u16 len = sizeof(*params); 1972 1973 /* handled by cnic driver */ 1974 hba->cnic->iscsi_nl_msg_recv(hba->cnic, ISCSI_UEVENT_PATH_UPDATE, buf, 1975 len); 1976 1977 return 0; 1978 } 1979 1980 1981 /* 1982 * 'Scsi_Host_Template' structure and 'iscsi_tranport' structure template 1983 * used while registering with the scsi host and iSCSI transport module. 1984 */ 1985 static struct scsi_host_template bnx2i_host_template = { 1986 .module = THIS_MODULE, 1987 .name = "Broadcom Offload iSCSI Initiator", 1988 .proc_name = "bnx2i", 1989 .queuecommand = iscsi_queuecommand, 1990 .eh_abort_handler = iscsi_eh_abort, 1991 .eh_device_reset_handler = iscsi_eh_device_reset, 1992 .eh_target_reset_handler = iscsi_eh_target_reset, 1993 .can_queue = 1024, 1994 .max_sectors = 127, 1995 .cmd_per_lun = 32, 1996 .this_id = -1, 1997 .use_clustering = ENABLE_CLUSTERING, 1998 .sg_tablesize = ISCSI_MAX_BDS_PER_CMD, 1999 .shost_attrs = bnx2i_dev_attributes, 2000 }; 2001 2002 struct iscsi_transport bnx2i_iscsi_transport = { 2003 .owner = THIS_MODULE, 2004 .name = "bnx2i", 2005 .caps = CAP_RECOVERY_L0 | CAP_HDRDGST | 2006 CAP_MULTI_R2T | CAP_DATADGST | 2007 CAP_DATA_PATH_OFFLOAD, 2008 .param_mask = ISCSI_MAX_RECV_DLENGTH | 2009 ISCSI_MAX_XMIT_DLENGTH | 2010 ISCSI_HDRDGST_EN | 2011 ISCSI_DATADGST_EN | 2012 ISCSI_INITIAL_R2T_EN | 2013 ISCSI_MAX_R2T | 2014 ISCSI_IMM_DATA_EN | 2015 ISCSI_FIRST_BURST | 2016 ISCSI_MAX_BURST | 2017 ISCSI_PDU_INORDER_EN | 2018 ISCSI_DATASEQ_INORDER_EN | 2019 ISCSI_ERL | 2020 ISCSI_CONN_PORT | 2021 ISCSI_CONN_ADDRESS | 2022 ISCSI_EXP_STATSN | 2023 ISCSI_PERSISTENT_PORT | 2024 ISCSI_PERSISTENT_ADDRESS | 2025 ISCSI_TARGET_NAME | ISCSI_TPGT | 2026 ISCSI_USERNAME | ISCSI_PASSWORD | 2027 ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN | 2028 ISCSI_FAST_ABORT | ISCSI_ABORT_TMO | 2029 ISCSI_LU_RESET_TMO | ISCSI_TGT_RESET_TMO | 2030 ISCSI_PING_TMO | ISCSI_RECV_TMO | 2031 ISCSI_IFACE_NAME | ISCSI_INITIATOR_NAME, 2032 .host_param_mask = ISCSI_HOST_HWADDRESS | ISCSI_HOST_NETDEV_NAME, 2033 .create_session = bnx2i_session_create, 2034 .destroy_session = bnx2i_session_destroy, 2035 .create_conn = bnx2i_conn_create, 2036 .bind_conn = bnx2i_conn_bind, 2037 .destroy_conn = bnx2i_conn_destroy, 2038 .set_param = iscsi_set_param, 2039 .get_conn_param = bnx2i_conn_get_param, 2040 .get_session_param = iscsi_session_get_param, 2041 .get_host_param = bnx2i_host_get_param, 2042 .start_conn = bnx2i_conn_start, 2043 .stop_conn = iscsi_conn_stop, 2044 .send_pdu = iscsi_conn_send_pdu, 2045 .xmit_task = bnx2i_task_xmit, 2046 .get_stats = bnx2i_conn_get_stats, 2047 /* TCP connect - disconnect - option-2 interface calls */ 2048 .ep_connect = bnx2i_ep_connect, 2049 .ep_poll = bnx2i_ep_poll, 2050 .ep_disconnect = bnx2i_ep_disconnect, 2051 .set_path = bnx2i_nl_set_path, 2052 /* Error recovery timeout call */ 2053 .session_recovery_timedout = iscsi_session_recovery_timedout, 2054 .cleanup_task = bnx2i_cleanup_task, 2055 }; 2056