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 /* Anil */ 489 task->hdr = &cmd->hdr; 490 task->hdr_max = sizeof(struct iscsi_hdr); 491 492 if (bnx2i_alloc_bdt(hba, session, cmd)) 493 goto free_bdts; 494 } 495 496 return 0; 497 498 free_bdts: 499 bnx2i_destroy_cmd_pool(hba, session); 500 return -ENOMEM; 501 } 502 503 504 /** 505 * bnx2i_setup_mp_bdt - allocate BD table resources 506 * @hba: pointer to adapter structure 507 * 508 * Allocate memory for dummy buffer and associated BD 509 * table to be used by middle path (MP) requests 510 */ 511 static int bnx2i_setup_mp_bdt(struct bnx2i_hba *hba) 512 { 513 int rc = 0; 514 struct iscsi_bd *mp_bdt; 515 u64 addr; 516 517 hba->mp_bd_tbl = dma_alloc_coherent(&hba->pcidev->dev, PAGE_SIZE, 518 &hba->mp_bd_dma, GFP_KERNEL); 519 if (!hba->mp_bd_tbl) { 520 printk(KERN_ERR "unable to allocate Middle Path BDT\n"); 521 rc = -1; 522 goto out; 523 } 524 525 hba->dummy_buffer = dma_alloc_coherent(&hba->pcidev->dev, PAGE_SIZE, 526 &hba->dummy_buf_dma, GFP_KERNEL); 527 if (!hba->dummy_buffer) { 528 printk(KERN_ERR "unable to alloc Middle Path Dummy Buffer\n"); 529 dma_free_coherent(&hba->pcidev->dev, PAGE_SIZE, 530 hba->mp_bd_tbl, hba->mp_bd_dma); 531 hba->mp_bd_tbl = NULL; 532 rc = -1; 533 goto out; 534 } 535 536 mp_bdt = (struct iscsi_bd *) hba->mp_bd_tbl; 537 addr = (unsigned long) hba->dummy_buf_dma; 538 mp_bdt->buffer_addr_lo = addr & 0xffffffff; 539 mp_bdt->buffer_addr_hi = addr >> 32; 540 mp_bdt->buffer_length = PAGE_SIZE; 541 mp_bdt->flags = ISCSI_BD_LAST_IN_BD_CHAIN | 542 ISCSI_BD_FIRST_IN_BD_CHAIN; 543 out: 544 return rc; 545 } 546 547 548 /** 549 * bnx2i_free_mp_bdt - releases ITT back to free pool 550 * @hba: pointer to adapter instance 551 * 552 * free MP dummy buffer and associated BD table 553 */ 554 static void bnx2i_free_mp_bdt(struct bnx2i_hba *hba) 555 { 556 if (hba->mp_bd_tbl) { 557 dma_free_coherent(&hba->pcidev->dev, PAGE_SIZE, 558 hba->mp_bd_tbl, hba->mp_bd_dma); 559 hba->mp_bd_tbl = NULL; 560 } 561 if (hba->dummy_buffer) { 562 dma_free_coherent(&hba->pcidev->dev, PAGE_SIZE, 563 hba->dummy_buffer, hba->dummy_buf_dma); 564 hba->dummy_buffer = NULL; 565 } 566 return; 567 } 568 569 /** 570 * bnx2i_drop_session - notifies iscsid of connection error. 571 * @hba: adapter instance pointer 572 * @session: iscsi session pointer 573 * 574 * This notifies iscsid that there is a error, so it can initiate 575 * recovery. 576 * 577 * This relies on caller using the iscsi class iterator so the object 578 * is refcounted and does not disapper from under us. 579 */ 580 void bnx2i_drop_session(struct iscsi_cls_session *cls_session) 581 { 582 iscsi_session_failure(cls_session->dd_data, ISCSI_ERR_CONN_FAILED); 583 } 584 585 /** 586 * bnx2i_ep_destroy_list_add - add an entry to EP destroy list 587 * @hba: pointer to adapter instance 588 * @ep: pointer to endpoint (transport indentifier) structure 589 * 590 * EP destroy queue manager 591 */ 592 static int bnx2i_ep_destroy_list_add(struct bnx2i_hba *hba, 593 struct bnx2i_endpoint *ep) 594 { 595 write_lock_bh(&hba->ep_rdwr_lock); 596 list_add_tail(&ep->link, &hba->ep_destroy_list); 597 write_unlock_bh(&hba->ep_rdwr_lock); 598 return 0; 599 } 600 601 /** 602 * bnx2i_ep_destroy_list_del - add an entry to EP destroy list 603 * 604 * @hba: pointer to adapter instance 605 * @ep: pointer to endpoint (transport indentifier) structure 606 * 607 * EP destroy queue manager 608 */ 609 static int bnx2i_ep_destroy_list_del(struct bnx2i_hba *hba, 610 struct bnx2i_endpoint *ep) 611 { 612 write_lock_bh(&hba->ep_rdwr_lock); 613 list_del_init(&ep->link); 614 write_unlock_bh(&hba->ep_rdwr_lock); 615 616 return 0; 617 } 618 619 /** 620 * bnx2i_ep_ofld_list_add - add an entry to ep offload pending list 621 * @hba: pointer to adapter instance 622 * @ep: pointer to endpoint (transport indentifier) structure 623 * 624 * pending conn offload completion queue manager 625 */ 626 static int bnx2i_ep_ofld_list_add(struct bnx2i_hba *hba, 627 struct bnx2i_endpoint *ep) 628 { 629 write_lock_bh(&hba->ep_rdwr_lock); 630 list_add_tail(&ep->link, &hba->ep_ofld_list); 631 write_unlock_bh(&hba->ep_rdwr_lock); 632 return 0; 633 } 634 635 /** 636 * bnx2i_ep_ofld_list_del - add an entry to ep offload pending list 637 * @hba: pointer to adapter instance 638 * @ep: pointer to endpoint (transport indentifier) structure 639 * 640 * pending conn offload completion queue manager 641 */ 642 static int bnx2i_ep_ofld_list_del(struct bnx2i_hba *hba, 643 struct bnx2i_endpoint *ep) 644 { 645 write_lock_bh(&hba->ep_rdwr_lock); 646 list_del_init(&ep->link); 647 write_unlock_bh(&hba->ep_rdwr_lock); 648 return 0; 649 } 650 651 652 /** 653 * bnx2i_find_ep_in_ofld_list - find iscsi_cid in pending list of endpoints 654 * 655 * @hba: pointer to adapter instance 656 * @iscsi_cid: iscsi context ID to find 657 * 658 */ 659 struct bnx2i_endpoint * 660 bnx2i_find_ep_in_ofld_list(struct bnx2i_hba *hba, u32 iscsi_cid) 661 { 662 struct list_head *list; 663 struct list_head *tmp; 664 struct bnx2i_endpoint *ep; 665 666 read_lock_bh(&hba->ep_rdwr_lock); 667 list_for_each_safe(list, tmp, &hba->ep_ofld_list) { 668 ep = (struct bnx2i_endpoint *)list; 669 670 if (ep->ep_iscsi_cid == iscsi_cid) 671 break; 672 ep = NULL; 673 } 674 read_unlock_bh(&hba->ep_rdwr_lock); 675 676 if (!ep) 677 printk(KERN_ERR "l5 cid %d not found\n", iscsi_cid); 678 return ep; 679 } 680 681 682 /** 683 * bnx2i_find_ep_in_destroy_list - find iscsi_cid in destroy list 684 * @hba: pointer to adapter instance 685 * @iscsi_cid: iscsi context ID to find 686 * 687 */ 688 struct bnx2i_endpoint * 689 bnx2i_find_ep_in_destroy_list(struct bnx2i_hba *hba, u32 iscsi_cid) 690 { 691 struct list_head *list; 692 struct list_head *tmp; 693 struct bnx2i_endpoint *ep; 694 695 read_lock_bh(&hba->ep_rdwr_lock); 696 list_for_each_safe(list, tmp, &hba->ep_destroy_list) { 697 ep = (struct bnx2i_endpoint *)list; 698 699 if (ep->ep_iscsi_cid == iscsi_cid) 700 break; 701 ep = NULL; 702 } 703 read_unlock_bh(&hba->ep_rdwr_lock); 704 705 if (!ep) 706 printk(KERN_ERR "l5 cid %d not found\n", iscsi_cid); 707 708 return ep; 709 } 710 711 /** 712 * bnx2i_setup_host_queue_size - assigns shost->can_queue param 713 * @hba: pointer to adapter instance 714 * @shost: scsi host pointer 715 * 716 * Initializes 'can_queue' parameter based on how many outstanding commands 717 * the device can handle. Each device 5708/5709/57710 has different 718 * capabilities 719 */ 720 static void bnx2i_setup_host_queue_size(struct bnx2i_hba *hba, 721 struct Scsi_Host *shost) 722 { 723 if (test_bit(BNX2I_NX2_DEV_5708, &hba->cnic_dev_type)) 724 shost->can_queue = ISCSI_MAX_CMDS_PER_HBA_5708; 725 else if (test_bit(BNX2I_NX2_DEV_5709, &hba->cnic_dev_type)) 726 shost->can_queue = ISCSI_MAX_CMDS_PER_HBA_5709; 727 else if (test_bit(BNX2I_NX2_DEV_57710, &hba->cnic_dev_type)) 728 shost->can_queue = ISCSI_MAX_CMDS_PER_HBA_57710; 729 else 730 shost->can_queue = ISCSI_MAX_CMDS_PER_HBA_5708; 731 } 732 733 734 /** 735 * bnx2i_alloc_hba - allocate and init adapter instance 736 * @cnic: cnic device pointer 737 * 738 * allocate & initialize adapter structure and call other 739 * support routines to do per adapter initialization 740 */ 741 struct bnx2i_hba *bnx2i_alloc_hba(struct cnic_dev *cnic) 742 { 743 struct Scsi_Host *shost; 744 struct bnx2i_hba *hba; 745 746 shost = iscsi_host_alloc(&bnx2i_host_template, sizeof(*hba), 0); 747 if (!shost) 748 return NULL; 749 shost->dma_boundary = cnic->pcidev->dma_mask; 750 shost->transportt = bnx2i_scsi_xport_template; 751 shost->max_id = ISCSI_MAX_CONNS_PER_HBA; 752 shost->max_channel = 0; 753 shost->max_lun = 512; 754 shost->max_cmd_len = 16; 755 756 hba = iscsi_host_priv(shost); 757 hba->shost = shost; 758 hba->netdev = cnic->netdev; 759 /* Get PCI related information and update hba struct members */ 760 hba->pcidev = cnic->pcidev; 761 pci_dev_get(hba->pcidev); 762 hba->pci_did = hba->pcidev->device; 763 hba->pci_vid = hba->pcidev->vendor; 764 hba->pci_sdid = hba->pcidev->subsystem_device; 765 hba->pci_svid = hba->pcidev->subsystem_vendor; 766 hba->pci_func = PCI_FUNC(hba->pcidev->devfn); 767 hba->pci_devno = PCI_SLOT(hba->pcidev->devfn); 768 bnx2i_identify_device(hba); 769 770 bnx2i_identify_device(hba); 771 bnx2i_setup_host_queue_size(hba, shost); 772 773 if (test_bit(BNX2I_NX2_DEV_5709, &hba->cnic_dev_type)) { 774 hba->regview = ioremap_nocache(hba->netdev->base_addr, 775 BNX2_MQ_CONFIG2); 776 if (!hba->regview) 777 goto ioreg_map_err; 778 } else if (test_bit(BNX2I_NX2_DEV_57710, &hba->cnic_dev_type)) { 779 hba->regview = ioremap_nocache(hba->netdev->base_addr, 4096); 780 if (!hba->regview) 781 goto ioreg_map_err; 782 } 783 784 if (bnx2i_setup_mp_bdt(hba)) 785 goto mp_bdt_mem_err; 786 787 INIT_LIST_HEAD(&hba->ep_ofld_list); 788 INIT_LIST_HEAD(&hba->ep_destroy_list); 789 rwlock_init(&hba->ep_rdwr_lock); 790 791 hba->mtu_supported = BNX2I_MAX_MTU_SUPPORTED; 792 793 /* different values for 5708/5709/57710 */ 794 hba->max_active_conns = ISCSI_MAX_CONNS_PER_HBA; 795 796 if (bnx2i_setup_free_cid_que(hba)) 797 goto cid_que_err; 798 799 /* SQ/RQ/CQ size can be changed via sysfx interface */ 800 if (test_bit(BNX2I_NX2_DEV_57710, &hba->cnic_dev_type)) { 801 if (sq_size && sq_size <= BNX2I_5770X_SQ_WQES_MAX) 802 hba->max_sqes = sq_size; 803 else 804 hba->max_sqes = BNX2I_5770X_SQ_WQES_DEFAULT; 805 } else { /* 5706/5708/5709 */ 806 if (sq_size && sq_size <= BNX2I_570X_SQ_WQES_MAX) 807 hba->max_sqes = sq_size; 808 else 809 hba->max_sqes = BNX2I_570X_SQ_WQES_DEFAULT; 810 } 811 812 hba->max_rqes = rq_size; 813 hba->max_cqes = hba->max_sqes + rq_size; 814 if (test_bit(BNX2I_NX2_DEV_57710, &hba->cnic_dev_type)) { 815 if (hba->max_cqes > BNX2I_5770X_CQ_WQES_MAX) 816 hba->max_cqes = BNX2I_5770X_CQ_WQES_MAX; 817 } else if (hba->max_cqes > BNX2I_570X_CQ_WQES_MAX) 818 hba->max_cqes = BNX2I_570X_CQ_WQES_MAX; 819 820 hba->num_ccell = hba->max_sqes / 2; 821 822 spin_lock_init(&hba->lock); 823 mutex_init(&hba->net_dev_lock); 824 825 if (iscsi_host_add(shost, &hba->pcidev->dev)) 826 goto free_dump_mem; 827 return hba; 828 829 free_dump_mem: 830 bnx2i_release_free_cid_que(hba); 831 cid_que_err: 832 bnx2i_free_mp_bdt(hba); 833 mp_bdt_mem_err: 834 if (hba->regview) { 835 iounmap(hba->regview); 836 hba->regview = NULL; 837 } 838 ioreg_map_err: 839 pci_dev_put(hba->pcidev); 840 scsi_host_put(shost); 841 return NULL; 842 } 843 844 /** 845 * bnx2i_free_hba- releases hba structure and resources held by the adapter 846 * @hba: pointer to adapter instance 847 * 848 * free adapter structure and call various cleanup routines. 849 */ 850 void bnx2i_free_hba(struct bnx2i_hba *hba) 851 { 852 struct Scsi_Host *shost = hba->shost; 853 854 iscsi_host_remove(shost); 855 INIT_LIST_HEAD(&hba->ep_ofld_list); 856 INIT_LIST_HEAD(&hba->ep_destroy_list); 857 pci_dev_put(hba->pcidev); 858 859 if (hba->regview) { 860 iounmap(hba->regview); 861 hba->regview = NULL; 862 } 863 bnx2i_free_mp_bdt(hba); 864 bnx2i_release_free_cid_que(hba); 865 iscsi_host_free(shost); 866 } 867 868 /** 869 * bnx2i_conn_free_login_resources - free DMA resources used for login process 870 * @hba: pointer to adapter instance 871 * @bnx2i_conn: iscsi connection pointer 872 * 873 * Login related resources, mostly BDT & payload DMA memory is freed 874 */ 875 static void bnx2i_conn_free_login_resources(struct bnx2i_hba *hba, 876 struct bnx2i_conn *bnx2i_conn) 877 { 878 if (bnx2i_conn->gen_pdu.resp_bd_tbl) { 879 dma_free_coherent(&hba->pcidev->dev, PAGE_SIZE, 880 bnx2i_conn->gen_pdu.resp_bd_tbl, 881 bnx2i_conn->gen_pdu.resp_bd_dma); 882 bnx2i_conn->gen_pdu.resp_bd_tbl = NULL; 883 } 884 885 if (bnx2i_conn->gen_pdu.req_bd_tbl) { 886 dma_free_coherent(&hba->pcidev->dev, PAGE_SIZE, 887 bnx2i_conn->gen_pdu.req_bd_tbl, 888 bnx2i_conn->gen_pdu.req_bd_dma); 889 bnx2i_conn->gen_pdu.req_bd_tbl = NULL; 890 } 891 892 if (bnx2i_conn->gen_pdu.resp_buf) { 893 dma_free_coherent(&hba->pcidev->dev, 894 ISCSI_DEF_MAX_RECV_SEG_LEN, 895 bnx2i_conn->gen_pdu.resp_buf, 896 bnx2i_conn->gen_pdu.resp_dma_addr); 897 bnx2i_conn->gen_pdu.resp_buf = NULL; 898 } 899 900 if (bnx2i_conn->gen_pdu.req_buf) { 901 dma_free_coherent(&hba->pcidev->dev, 902 ISCSI_DEF_MAX_RECV_SEG_LEN, 903 bnx2i_conn->gen_pdu.req_buf, 904 bnx2i_conn->gen_pdu.req_dma_addr); 905 bnx2i_conn->gen_pdu.req_buf = NULL; 906 } 907 } 908 909 /** 910 * bnx2i_conn_alloc_login_resources - alloc DMA resources for login/nop. 911 * @hba: pointer to adapter instance 912 * @bnx2i_conn: iscsi connection pointer 913 * 914 * Mgmt task DNA resources are allocated in this routine. 915 */ 916 static int bnx2i_conn_alloc_login_resources(struct bnx2i_hba *hba, 917 struct bnx2i_conn *bnx2i_conn) 918 { 919 /* Allocate memory for login request/response buffers */ 920 bnx2i_conn->gen_pdu.req_buf = 921 dma_alloc_coherent(&hba->pcidev->dev, 922 ISCSI_DEF_MAX_RECV_SEG_LEN, 923 &bnx2i_conn->gen_pdu.req_dma_addr, 924 GFP_KERNEL); 925 if (bnx2i_conn->gen_pdu.req_buf == NULL) 926 goto login_req_buf_failure; 927 928 bnx2i_conn->gen_pdu.req_buf_size = 0; 929 bnx2i_conn->gen_pdu.req_wr_ptr = bnx2i_conn->gen_pdu.req_buf; 930 931 bnx2i_conn->gen_pdu.resp_buf = 932 dma_alloc_coherent(&hba->pcidev->dev, 933 ISCSI_DEF_MAX_RECV_SEG_LEN, 934 &bnx2i_conn->gen_pdu.resp_dma_addr, 935 GFP_KERNEL); 936 if (bnx2i_conn->gen_pdu.resp_buf == NULL) 937 goto login_resp_buf_failure; 938 939 bnx2i_conn->gen_pdu.resp_buf_size = ISCSI_DEF_MAX_RECV_SEG_LEN; 940 bnx2i_conn->gen_pdu.resp_wr_ptr = bnx2i_conn->gen_pdu.resp_buf; 941 942 bnx2i_conn->gen_pdu.req_bd_tbl = 943 dma_alloc_coherent(&hba->pcidev->dev, PAGE_SIZE, 944 &bnx2i_conn->gen_pdu.req_bd_dma, GFP_KERNEL); 945 if (bnx2i_conn->gen_pdu.req_bd_tbl == NULL) 946 goto login_req_bd_tbl_failure; 947 948 bnx2i_conn->gen_pdu.resp_bd_tbl = 949 dma_alloc_coherent(&hba->pcidev->dev, PAGE_SIZE, 950 &bnx2i_conn->gen_pdu.resp_bd_dma, 951 GFP_KERNEL); 952 if (bnx2i_conn->gen_pdu.resp_bd_tbl == NULL) 953 goto login_resp_bd_tbl_failure; 954 955 return 0; 956 957 login_resp_bd_tbl_failure: 958 dma_free_coherent(&hba->pcidev->dev, PAGE_SIZE, 959 bnx2i_conn->gen_pdu.req_bd_tbl, 960 bnx2i_conn->gen_pdu.req_bd_dma); 961 bnx2i_conn->gen_pdu.req_bd_tbl = NULL; 962 963 login_req_bd_tbl_failure: 964 dma_free_coherent(&hba->pcidev->dev, ISCSI_DEF_MAX_RECV_SEG_LEN, 965 bnx2i_conn->gen_pdu.resp_buf, 966 bnx2i_conn->gen_pdu.resp_dma_addr); 967 bnx2i_conn->gen_pdu.resp_buf = NULL; 968 login_resp_buf_failure: 969 dma_free_coherent(&hba->pcidev->dev, ISCSI_DEF_MAX_RECV_SEG_LEN, 970 bnx2i_conn->gen_pdu.req_buf, 971 bnx2i_conn->gen_pdu.req_dma_addr); 972 bnx2i_conn->gen_pdu.req_buf = NULL; 973 login_req_buf_failure: 974 iscsi_conn_printk(KERN_ERR, bnx2i_conn->cls_conn->dd_data, 975 "login resource alloc failed!!\n"); 976 return -ENOMEM; 977 978 } 979 980 981 /** 982 * bnx2i_iscsi_prep_generic_pdu_bd - prepares BD table. 983 * @bnx2i_conn: iscsi connection pointer 984 * 985 * Allocates buffers and BD tables before shipping requests to cnic 986 * for PDUs prepared by 'iscsid' daemon 987 */ 988 static void bnx2i_iscsi_prep_generic_pdu_bd(struct bnx2i_conn *bnx2i_conn) 989 { 990 struct iscsi_bd *bd_tbl; 991 992 bd_tbl = (struct iscsi_bd *) bnx2i_conn->gen_pdu.req_bd_tbl; 993 994 bd_tbl->buffer_addr_hi = 995 (u32) ((u64) bnx2i_conn->gen_pdu.req_dma_addr >> 32); 996 bd_tbl->buffer_addr_lo = (u32) bnx2i_conn->gen_pdu.req_dma_addr; 997 bd_tbl->buffer_length = bnx2i_conn->gen_pdu.req_wr_ptr - 998 bnx2i_conn->gen_pdu.req_buf; 999 bd_tbl->reserved0 = 0; 1000 bd_tbl->flags = ISCSI_BD_LAST_IN_BD_CHAIN | 1001 ISCSI_BD_FIRST_IN_BD_CHAIN; 1002 1003 bd_tbl = (struct iscsi_bd *) bnx2i_conn->gen_pdu.resp_bd_tbl; 1004 bd_tbl->buffer_addr_hi = (u64) bnx2i_conn->gen_pdu.resp_dma_addr >> 32; 1005 bd_tbl->buffer_addr_lo = (u32) bnx2i_conn->gen_pdu.resp_dma_addr; 1006 bd_tbl->buffer_length = ISCSI_DEF_MAX_RECV_SEG_LEN; 1007 bd_tbl->reserved0 = 0; 1008 bd_tbl->flags = ISCSI_BD_LAST_IN_BD_CHAIN | 1009 ISCSI_BD_FIRST_IN_BD_CHAIN; 1010 } 1011 1012 1013 /** 1014 * bnx2i_iscsi_send_generic_request - called to send mgmt tasks. 1015 * @task: transport layer task pointer 1016 * 1017 * called to transmit PDUs prepared by the 'iscsid' daemon. iSCSI login, 1018 * Nop-out and Logout requests flow through this path. 1019 */ 1020 static int bnx2i_iscsi_send_generic_request(struct iscsi_task *task) 1021 { 1022 struct bnx2i_cmd *cmd = task->dd_data; 1023 struct bnx2i_conn *bnx2i_conn = cmd->conn; 1024 int rc = 0; 1025 char *buf; 1026 int data_len; 1027 1028 bnx2i_iscsi_prep_generic_pdu_bd(bnx2i_conn); 1029 switch (task->hdr->opcode & ISCSI_OPCODE_MASK) { 1030 case ISCSI_OP_LOGIN: 1031 bnx2i_send_iscsi_login(bnx2i_conn, task); 1032 break; 1033 case ISCSI_OP_NOOP_OUT: 1034 data_len = bnx2i_conn->gen_pdu.req_buf_size; 1035 buf = bnx2i_conn->gen_pdu.req_buf; 1036 if (data_len) 1037 rc = bnx2i_send_iscsi_nopout(bnx2i_conn, task, 1038 RESERVED_ITT, 1039 buf, data_len, 1); 1040 else 1041 rc = bnx2i_send_iscsi_nopout(bnx2i_conn, task, 1042 RESERVED_ITT, 1043 NULL, 0, 1); 1044 break; 1045 case ISCSI_OP_LOGOUT: 1046 rc = bnx2i_send_iscsi_logout(bnx2i_conn, task); 1047 break; 1048 case ISCSI_OP_SCSI_TMFUNC: 1049 rc = bnx2i_send_iscsi_tmf(bnx2i_conn, task); 1050 break; 1051 default: 1052 iscsi_conn_printk(KERN_ALERT, bnx2i_conn->cls_conn->dd_data, 1053 "send_gen: unsupported op 0x%x\n", 1054 task->hdr->opcode); 1055 } 1056 return rc; 1057 } 1058 1059 1060 /********************************************************************** 1061 * SCSI-ML Interface 1062 **********************************************************************/ 1063 1064 /** 1065 * bnx2i_cpy_scsi_cdb - copies LUN & CDB fields in required format to sq wqe 1066 * @sc: SCSI-ML command pointer 1067 * @cmd: iscsi cmd pointer 1068 */ 1069 static void bnx2i_cpy_scsi_cdb(struct scsi_cmnd *sc, struct bnx2i_cmd *cmd) 1070 { 1071 u32 dword; 1072 int lpcnt; 1073 u8 *srcp; 1074 u32 *dstp; 1075 u32 scsi_lun[2]; 1076 1077 int_to_scsilun(sc->device->lun, (struct scsi_lun *) scsi_lun); 1078 cmd->req.lun[0] = be32_to_cpu(scsi_lun[0]); 1079 cmd->req.lun[1] = be32_to_cpu(scsi_lun[1]); 1080 1081 lpcnt = cmd->scsi_cmd->cmd_len / sizeof(dword); 1082 srcp = (u8 *) sc->cmnd; 1083 dstp = (u32 *) cmd->req.cdb; 1084 while (lpcnt--) { 1085 memcpy(&dword, (const void *) srcp, 4); 1086 *dstp = cpu_to_be32(dword); 1087 srcp += 4; 1088 dstp++; 1089 } 1090 if (sc->cmd_len & 0x3) { 1091 dword = (u32) srcp[0] | ((u32) srcp[1] << 8); 1092 *dstp = cpu_to_be32(dword); 1093 } 1094 } 1095 1096 static void bnx2i_cleanup_task(struct iscsi_task *task) 1097 { 1098 struct iscsi_conn *conn = task->conn; 1099 struct bnx2i_conn *bnx2i_conn = conn->dd_data; 1100 struct bnx2i_hba *hba = bnx2i_conn->hba; 1101 1102 /* 1103 * mgmt task or cmd was never sent to us to transmit. 1104 */ 1105 if (!task->sc || task->state == ISCSI_TASK_PENDING) 1106 return; 1107 /* 1108 * need to clean-up task context to claim dma buffers 1109 */ 1110 if (task->state == ISCSI_TASK_ABRT_TMF) { 1111 bnx2i_send_cmd_cleanup_req(hba, task->dd_data); 1112 1113 spin_unlock_bh(&conn->session->lock); 1114 wait_for_completion_timeout(&bnx2i_conn->cmd_cleanup_cmpl, 1115 msecs_to_jiffies(ISCSI_CMD_CLEANUP_TIMEOUT)); 1116 spin_lock_bh(&conn->session->lock); 1117 } 1118 bnx2i_iscsi_unmap_sg_list(task->dd_data); 1119 } 1120 1121 /** 1122 * bnx2i_mtask_xmit - transmit mtask to chip for further processing 1123 * @conn: transport layer conn structure pointer 1124 * @task: transport layer command structure pointer 1125 */ 1126 static int 1127 bnx2i_mtask_xmit(struct iscsi_conn *conn, struct iscsi_task *task) 1128 { 1129 struct bnx2i_conn *bnx2i_conn = conn->dd_data; 1130 struct bnx2i_cmd *cmd = task->dd_data; 1131 1132 memset(bnx2i_conn->gen_pdu.req_buf, 0, ISCSI_DEF_MAX_RECV_SEG_LEN); 1133 1134 bnx2i_setup_cmd_wqe_template(cmd); 1135 bnx2i_conn->gen_pdu.req_buf_size = task->data_count; 1136 if (task->data_count) { 1137 memcpy(bnx2i_conn->gen_pdu.req_buf, task->data, 1138 task->data_count); 1139 bnx2i_conn->gen_pdu.req_wr_ptr = 1140 bnx2i_conn->gen_pdu.req_buf + task->data_count; 1141 } 1142 cmd->conn = conn->dd_data; 1143 cmd->scsi_cmd = NULL; 1144 return bnx2i_iscsi_send_generic_request(task); 1145 } 1146 1147 /** 1148 * bnx2i_task_xmit - transmit iscsi command to chip for further processing 1149 * @task: transport layer command structure pointer 1150 * 1151 * maps SG buffers and send request to chip/firmware in the form of SQ WQE 1152 */ 1153 static int bnx2i_task_xmit(struct iscsi_task *task) 1154 { 1155 struct iscsi_conn *conn = task->conn; 1156 struct iscsi_session *session = conn->session; 1157 struct Scsi_Host *shost = iscsi_session_to_shost(session->cls_session); 1158 struct bnx2i_hba *hba = iscsi_host_priv(shost); 1159 struct bnx2i_conn *bnx2i_conn = conn->dd_data; 1160 struct scsi_cmnd *sc = task->sc; 1161 struct bnx2i_cmd *cmd = task->dd_data; 1162 struct iscsi_cmd *hdr = (struct iscsi_cmd *) task->hdr; 1163 1164 if (!bnx2i_conn->is_bound) 1165 return -ENOTCONN; 1166 1167 /* 1168 * If there is no scsi_cmnd this must be a mgmt task 1169 */ 1170 if (!sc) 1171 return bnx2i_mtask_xmit(conn, task); 1172 1173 bnx2i_setup_cmd_wqe_template(cmd); 1174 cmd->req.op_code = ISCSI_OP_SCSI_CMD; 1175 cmd->conn = bnx2i_conn; 1176 cmd->scsi_cmd = sc; 1177 cmd->req.total_data_transfer_length = scsi_bufflen(sc); 1178 cmd->req.cmd_sn = be32_to_cpu(hdr->cmdsn); 1179 1180 bnx2i_iscsi_map_sg_list(cmd); 1181 bnx2i_cpy_scsi_cdb(sc, cmd); 1182 1183 cmd->req.op_attr = ISCSI_ATTR_SIMPLE; 1184 if (sc->sc_data_direction == DMA_TO_DEVICE) { 1185 cmd->req.op_attr |= ISCSI_CMD_REQUEST_WRITE; 1186 cmd->req.itt = task->itt | 1187 (ISCSI_TASK_TYPE_WRITE << ISCSI_CMD_REQUEST_TYPE_SHIFT); 1188 bnx2i_setup_write_cmd_bd_info(task); 1189 } else { 1190 if (scsi_bufflen(sc)) 1191 cmd->req.op_attr |= ISCSI_CMD_REQUEST_READ; 1192 cmd->req.itt = task->itt | 1193 (ISCSI_TASK_TYPE_READ << ISCSI_CMD_REQUEST_TYPE_SHIFT); 1194 } 1195 1196 cmd->req.num_bds = cmd->io_tbl.bd_valid; 1197 if (!cmd->io_tbl.bd_valid) { 1198 cmd->req.bd_list_addr_lo = (u32) hba->mp_bd_dma; 1199 cmd->req.bd_list_addr_hi = (u32) ((u64) hba->mp_bd_dma >> 32); 1200 cmd->req.num_bds = 1; 1201 } 1202 1203 bnx2i_send_iscsi_scsicmd(bnx2i_conn, cmd); 1204 return 0; 1205 } 1206 1207 /** 1208 * bnx2i_session_create - create a new iscsi session 1209 * @cmds_max: max commands supported 1210 * @qdepth: scsi queue depth to support 1211 * @initial_cmdsn: initial iscsi CMDSN to be used for this session 1212 * 1213 * Creates a new iSCSI session instance on given device. 1214 */ 1215 static struct iscsi_cls_session * 1216 bnx2i_session_create(struct iscsi_endpoint *ep, 1217 uint16_t cmds_max, uint16_t qdepth, 1218 uint32_t initial_cmdsn) 1219 { 1220 struct Scsi_Host *shost; 1221 struct iscsi_cls_session *cls_session; 1222 struct bnx2i_hba *hba; 1223 struct bnx2i_endpoint *bnx2i_ep; 1224 1225 if (!ep) { 1226 printk(KERN_ERR "bnx2i: missing ep.\n"); 1227 return NULL; 1228 } 1229 1230 bnx2i_ep = ep->dd_data; 1231 shost = bnx2i_ep->hba->shost; 1232 hba = iscsi_host_priv(shost); 1233 if (bnx2i_adapter_ready(hba)) 1234 return NULL; 1235 1236 /* 1237 * user can override hw limit as long as it is within 1238 * the min/max. 1239 */ 1240 if (cmds_max > hba->max_sqes) 1241 cmds_max = hba->max_sqes; 1242 else if (cmds_max < BNX2I_SQ_WQES_MIN) 1243 cmds_max = BNX2I_SQ_WQES_MIN; 1244 1245 cls_session = iscsi_session_setup(&bnx2i_iscsi_transport, shost, 1246 cmds_max, sizeof(struct bnx2i_cmd), 1247 initial_cmdsn, ISCSI_MAX_TARGET); 1248 if (!cls_session) 1249 return NULL; 1250 1251 if (bnx2i_setup_cmd_pool(hba, cls_session->dd_data)) 1252 goto session_teardown; 1253 return cls_session; 1254 1255 session_teardown: 1256 iscsi_session_teardown(cls_session); 1257 return NULL; 1258 } 1259 1260 1261 /** 1262 * bnx2i_session_destroy - destroys iscsi session 1263 * @cls_session: pointer to iscsi cls session 1264 * 1265 * Destroys previously created iSCSI session instance and releases 1266 * all resources held by it 1267 */ 1268 static void bnx2i_session_destroy(struct iscsi_cls_session *cls_session) 1269 { 1270 struct iscsi_session *session = cls_session->dd_data; 1271 struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); 1272 struct bnx2i_hba *hba = iscsi_host_priv(shost); 1273 1274 bnx2i_destroy_cmd_pool(hba, session); 1275 iscsi_session_teardown(cls_session); 1276 } 1277 1278 1279 /** 1280 * bnx2i_conn_create - create iscsi connection instance 1281 * @cls_session: pointer to iscsi cls session 1282 * @cid: iscsi cid as per rfc (not NX2's CID terminology) 1283 * 1284 * Creates a new iSCSI connection instance for a given session 1285 */ 1286 static struct iscsi_cls_conn * 1287 bnx2i_conn_create(struct iscsi_cls_session *cls_session, uint32_t cid) 1288 { 1289 struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); 1290 struct bnx2i_hba *hba = iscsi_host_priv(shost); 1291 struct bnx2i_conn *bnx2i_conn; 1292 struct iscsi_cls_conn *cls_conn; 1293 struct iscsi_conn *conn; 1294 1295 cls_conn = iscsi_conn_setup(cls_session, sizeof(*bnx2i_conn), 1296 cid); 1297 if (!cls_conn) 1298 return NULL; 1299 conn = cls_conn->dd_data; 1300 1301 bnx2i_conn = conn->dd_data; 1302 bnx2i_conn->cls_conn = cls_conn; 1303 bnx2i_conn->hba = hba; 1304 /* 'ep' ptr will be assigned in bind() call */ 1305 bnx2i_conn->ep = NULL; 1306 init_completion(&bnx2i_conn->cmd_cleanup_cmpl); 1307 1308 if (bnx2i_conn_alloc_login_resources(hba, bnx2i_conn)) { 1309 iscsi_conn_printk(KERN_ALERT, conn, 1310 "conn_new: login resc alloc failed!!\n"); 1311 goto free_conn; 1312 } 1313 1314 return cls_conn; 1315 1316 free_conn: 1317 iscsi_conn_teardown(cls_conn); 1318 return NULL; 1319 } 1320 1321 /** 1322 * bnx2i_conn_bind - binds iscsi sess, conn and ep objects together 1323 * @cls_session: pointer to iscsi cls session 1324 * @cls_conn: pointer to iscsi cls conn 1325 * @transport_fd: 64-bit EP handle 1326 * @is_leading: leading connection on this session? 1327 * 1328 * Binds together iSCSI session instance, iSCSI connection instance 1329 * and the TCP connection. This routine returns error code if 1330 * TCP connection does not belong on the device iSCSI sess/conn 1331 * is bound 1332 */ 1333 static int bnx2i_conn_bind(struct iscsi_cls_session *cls_session, 1334 struct iscsi_cls_conn *cls_conn, 1335 uint64_t transport_fd, int is_leading) 1336 { 1337 struct iscsi_conn *conn = cls_conn->dd_data; 1338 struct bnx2i_conn *bnx2i_conn = conn->dd_data; 1339 struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); 1340 struct bnx2i_hba *hba = iscsi_host_priv(shost); 1341 struct bnx2i_endpoint *bnx2i_ep; 1342 struct iscsi_endpoint *ep; 1343 int ret_code; 1344 1345 ep = iscsi_lookup_endpoint(transport_fd); 1346 if (!ep) 1347 return -EINVAL; 1348 1349 bnx2i_ep = ep->dd_data; 1350 if ((bnx2i_ep->state == EP_STATE_TCP_FIN_RCVD) || 1351 (bnx2i_ep->state == EP_STATE_TCP_RST_RCVD)) 1352 /* Peer disconnect via' FIN or RST */ 1353 return -EINVAL; 1354 1355 if (iscsi_conn_bind(cls_session, cls_conn, is_leading)) 1356 return -EINVAL; 1357 1358 if (bnx2i_ep->hba != hba) { 1359 /* Error - TCP connection does not belong to this device 1360 */ 1361 iscsi_conn_printk(KERN_ALERT, cls_conn->dd_data, 1362 "conn bind, ep=0x%p (%s) does not", 1363 bnx2i_ep, bnx2i_ep->hba->netdev->name); 1364 iscsi_conn_printk(KERN_ALERT, cls_conn->dd_data, 1365 "belong to hba (%s)\n", 1366 hba->netdev->name); 1367 return -EEXIST; 1368 } 1369 1370 bnx2i_ep->conn = bnx2i_conn; 1371 bnx2i_conn->ep = bnx2i_ep; 1372 bnx2i_conn->iscsi_conn_cid = bnx2i_ep->ep_iscsi_cid; 1373 bnx2i_conn->fw_cid = bnx2i_ep->ep_cid; 1374 bnx2i_conn->is_bound = 1; 1375 1376 ret_code = bnx2i_bind_conn_to_iscsi_cid(hba, bnx2i_conn, 1377 bnx2i_ep->ep_iscsi_cid); 1378 1379 /* 5706/5708/5709 FW takes RQ as full when initiated, but for 57710 1380 * driver needs to explicitly replenish RQ index during setup. 1381 */ 1382 if (test_bit(BNX2I_NX2_DEV_57710, &bnx2i_ep->hba->cnic_dev_type)) 1383 bnx2i_put_rq_buf(bnx2i_conn, 0); 1384 1385 bnx2i_arm_cq_event_coalescing(bnx2i_conn->ep, CNIC_ARM_CQE); 1386 return ret_code; 1387 } 1388 1389 1390 /** 1391 * bnx2i_conn_destroy - destroy iscsi connection instance & release resources 1392 * @cls_conn: pointer to iscsi cls conn 1393 * 1394 * Destroy an iSCSI connection instance and release memory resources held by 1395 * this connection 1396 */ 1397 static void bnx2i_conn_destroy(struct iscsi_cls_conn *cls_conn) 1398 { 1399 struct iscsi_conn *conn = cls_conn->dd_data; 1400 struct bnx2i_conn *bnx2i_conn = conn->dd_data; 1401 struct Scsi_Host *shost; 1402 struct bnx2i_hba *hba; 1403 1404 shost = iscsi_session_to_shost(iscsi_conn_to_session(cls_conn)); 1405 hba = iscsi_host_priv(shost); 1406 1407 bnx2i_conn_free_login_resources(hba, bnx2i_conn); 1408 iscsi_conn_teardown(cls_conn); 1409 } 1410 1411 1412 /** 1413 * bnx2i_conn_get_param - return iscsi connection parameter to caller 1414 * @cls_conn: pointer to iscsi cls conn 1415 * @param: parameter type identifier 1416 * @buf: buffer pointer 1417 * 1418 * returns iSCSI connection parameters 1419 */ 1420 static int bnx2i_conn_get_param(struct iscsi_cls_conn *cls_conn, 1421 enum iscsi_param param, char *buf) 1422 { 1423 struct iscsi_conn *conn = cls_conn->dd_data; 1424 struct bnx2i_conn *bnx2i_conn = conn->dd_data; 1425 int len = 0; 1426 1427 switch (param) { 1428 case ISCSI_PARAM_CONN_PORT: 1429 if (bnx2i_conn->ep) 1430 len = sprintf(buf, "%hu\n", 1431 bnx2i_conn->ep->cm_sk->dst_port); 1432 break; 1433 case ISCSI_PARAM_CONN_ADDRESS: 1434 if (bnx2i_conn->ep) 1435 len = sprintf(buf, NIPQUAD_FMT "\n", 1436 NIPQUAD(bnx2i_conn->ep->cm_sk->dst_ip)); 1437 break; 1438 default: 1439 return iscsi_conn_get_param(cls_conn, param, buf); 1440 } 1441 1442 return len; 1443 } 1444 1445 /** 1446 * bnx2i_host_get_param - returns host (adapter) related parameters 1447 * @shost: scsi host pointer 1448 * @param: parameter type identifier 1449 * @buf: buffer pointer 1450 */ 1451 static int bnx2i_host_get_param(struct Scsi_Host *shost, 1452 enum iscsi_host_param param, char *buf) 1453 { 1454 struct bnx2i_hba *hba = iscsi_host_priv(shost); 1455 int len = 0; 1456 1457 switch (param) { 1458 case ISCSI_HOST_PARAM_HWADDRESS: 1459 len = sysfs_format_mac(buf, hba->cnic->mac_addr, 6); 1460 break; 1461 case ISCSI_HOST_PARAM_NETDEV_NAME: 1462 len = sprintf(buf, "%s\n", hba->netdev->name); 1463 break; 1464 default: 1465 return iscsi_host_get_param(shost, param, buf); 1466 } 1467 return len; 1468 } 1469 1470 /** 1471 * bnx2i_conn_start - completes iscsi connection migration to FFP 1472 * @cls_conn: pointer to iscsi cls conn 1473 * 1474 * last call in FFP migration to handover iscsi conn to the driver 1475 */ 1476 static int bnx2i_conn_start(struct iscsi_cls_conn *cls_conn) 1477 { 1478 struct iscsi_conn *conn = cls_conn->dd_data; 1479 struct bnx2i_conn *bnx2i_conn = conn->dd_data; 1480 1481 bnx2i_conn->ep->state = EP_STATE_ULP_UPDATE_START; 1482 bnx2i_update_iscsi_conn(conn); 1483 1484 /* 1485 * this should normally not sleep for a long time so it should 1486 * not disrupt the caller. 1487 */ 1488 bnx2i_conn->ep->ofld_timer.expires = 1 * HZ + jiffies; 1489 bnx2i_conn->ep->ofld_timer.function = bnx2i_ep_ofld_timer; 1490 bnx2i_conn->ep->ofld_timer.data = (unsigned long) bnx2i_conn->ep; 1491 add_timer(&bnx2i_conn->ep->ofld_timer); 1492 /* update iSCSI context for this conn, wait for CNIC to complete */ 1493 wait_event_interruptible(bnx2i_conn->ep->ofld_wait, 1494 bnx2i_conn->ep->state != EP_STATE_ULP_UPDATE_START); 1495 1496 if (signal_pending(current)) 1497 flush_signals(current); 1498 del_timer_sync(&bnx2i_conn->ep->ofld_timer); 1499 1500 iscsi_conn_start(cls_conn); 1501 return 0; 1502 } 1503 1504 1505 /** 1506 * bnx2i_conn_get_stats - returns iSCSI stats 1507 * @cls_conn: pointer to iscsi cls conn 1508 * @stats: pointer to iscsi statistic struct 1509 */ 1510 static void bnx2i_conn_get_stats(struct iscsi_cls_conn *cls_conn, 1511 struct iscsi_stats *stats) 1512 { 1513 struct iscsi_conn *conn = cls_conn->dd_data; 1514 1515 stats->txdata_octets = conn->txdata_octets; 1516 stats->rxdata_octets = conn->rxdata_octets; 1517 stats->scsicmd_pdus = conn->scsicmd_pdus_cnt; 1518 stats->dataout_pdus = conn->dataout_pdus_cnt; 1519 stats->scsirsp_pdus = conn->scsirsp_pdus_cnt; 1520 stats->datain_pdus = conn->datain_pdus_cnt; 1521 stats->r2t_pdus = conn->r2t_pdus_cnt; 1522 stats->tmfcmd_pdus = conn->tmfcmd_pdus_cnt; 1523 stats->tmfrsp_pdus = conn->tmfrsp_pdus_cnt; 1524 stats->custom_length = 3; 1525 strcpy(stats->custom[2].desc, "eh_abort_cnt"); 1526 stats->custom[2].value = conn->eh_abort_cnt; 1527 stats->digest_err = 0; 1528 stats->timeout_err = 0; 1529 stats->custom_length = 0; 1530 } 1531 1532 1533 /** 1534 * bnx2i_check_route - checks if target IP route belongs to one of NX2 devices 1535 * @dst_addr: target IP address 1536 * 1537 * check if route resolves to BNX2 device 1538 */ 1539 static struct bnx2i_hba *bnx2i_check_route(struct sockaddr *dst_addr) 1540 { 1541 struct sockaddr_in *desti = (struct sockaddr_in *) dst_addr; 1542 struct bnx2i_hba *hba; 1543 struct cnic_dev *cnic = NULL; 1544 1545 bnx2i_reg_dev_all(); 1546 1547 hba = get_adapter_list_head(); 1548 if (hba && hba->cnic) 1549 cnic = hba->cnic->cm_select_dev(desti, CNIC_ULP_ISCSI); 1550 if (!cnic) { 1551 printk(KERN_ALERT "bnx2i: no route," 1552 "can't connect using cnic\n"); 1553 goto no_nx2_route; 1554 } 1555 hba = bnx2i_find_hba_for_cnic(cnic); 1556 if (!hba) 1557 goto no_nx2_route; 1558 1559 if (bnx2i_adapter_ready(hba)) { 1560 printk(KERN_ALERT "bnx2i: check route, hba not found\n"); 1561 goto no_nx2_route; 1562 } 1563 if (hba->netdev->mtu > hba->mtu_supported) { 1564 printk(KERN_ALERT "bnx2i: %s network i/f mtu is set to %d\n", 1565 hba->netdev->name, hba->netdev->mtu); 1566 printk(KERN_ALERT "bnx2i: iSCSI HBA can support mtu of %d\n", 1567 hba->mtu_supported); 1568 goto no_nx2_route; 1569 } 1570 return hba; 1571 no_nx2_route: 1572 return NULL; 1573 } 1574 1575 1576 /** 1577 * bnx2i_tear_down_conn - tear down iscsi/tcp connection and free resources 1578 * @hba: pointer to adapter instance 1579 * @ep: endpoint (transport indentifier) structure 1580 * 1581 * destroys cm_sock structure and on chip iscsi context 1582 */ 1583 static int bnx2i_tear_down_conn(struct bnx2i_hba *hba, 1584 struct bnx2i_endpoint *ep) 1585 { 1586 if (test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic)) 1587 hba->cnic->cm_destroy(ep->cm_sk); 1588 1589 if (test_bit(ADAPTER_STATE_GOING_DOWN, &ep->hba->adapter_state)) 1590 ep->state = EP_STATE_DISCONN_COMPL; 1591 1592 if (test_bit(BNX2I_NX2_DEV_57710, &hba->cnic_dev_type) && 1593 ep->state == EP_STATE_DISCONN_TIMEDOUT) { 1594 printk(KERN_ALERT "bnx2i - ERROR - please submit GRC Dump," 1595 " NW/PCIe trace, driver msgs to developers" 1596 " for analysis\n"); 1597 return 1; 1598 } 1599 1600 ep->state = EP_STATE_CLEANUP_START; 1601 init_timer(&ep->ofld_timer); 1602 ep->ofld_timer.expires = 10*HZ + jiffies; 1603 ep->ofld_timer.function = bnx2i_ep_ofld_timer; 1604 ep->ofld_timer.data = (unsigned long) ep; 1605 add_timer(&ep->ofld_timer); 1606 1607 bnx2i_ep_destroy_list_add(hba, ep); 1608 1609 /* destroy iSCSI context, wait for it to complete */ 1610 bnx2i_send_conn_destroy(hba, ep); 1611 wait_event_interruptible(ep->ofld_wait, 1612 (ep->state != EP_STATE_CLEANUP_START)); 1613 1614 if (signal_pending(current)) 1615 flush_signals(current); 1616 del_timer_sync(&ep->ofld_timer); 1617 1618 bnx2i_ep_destroy_list_del(hba, ep); 1619 1620 if (ep->state != EP_STATE_CLEANUP_CMPL) 1621 /* should never happen */ 1622 printk(KERN_ALERT "bnx2i - conn destroy failed\n"); 1623 1624 return 0; 1625 } 1626 1627 1628 /** 1629 * bnx2i_ep_connect - establish TCP connection to target portal 1630 * @shost: scsi host 1631 * @dst_addr: target IP address 1632 * @non_blocking: blocking or non-blocking call 1633 * 1634 * this routine initiates the TCP/IP connection by invoking Option-2 i/f 1635 * with l5_core and the CNIC. This is a multi-step process of resolving 1636 * route to target, create a iscsi connection context, handshaking with 1637 * CNIC module to create/initialize the socket struct and finally 1638 * sending down option-2 request to complete TCP 3-way handshake 1639 */ 1640 static struct iscsi_endpoint *bnx2i_ep_connect(struct Scsi_Host *shost, 1641 struct sockaddr *dst_addr, 1642 int non_blocking) 1643 { 1644 u32 iscsi_cid = BNX2I_CID_RESERVED; 1645 struct sockaddr_in *desti = (struct sockaddr_in *) dst_addr; 1646 struct sockaddr_in6 *desti6; 1647 struct bnx2i_endpoint *bnx2i_ep; 1648 struct bnx2i_hba *hba; 1649 struct cnic_dev *cnic; 1650 struct cnic_sockaddr saddr; 1651 struct iscsi_endpoint *ep; 1652 int rc = 0; 1653 1654 if (shost) { 1655 /* driver is given scsi host to work with */ 1656 hba = iscsi_host_priv(shost); 1657 /* Register the device with cnic if not already done so */ 1658 bnx2i_register_device(hba); 1659 } else 1660 /* 1661 * check if the given destination can be reached through 1662 * a iscsi capable NetXtreme2 device 1663 */ 1664 hba = bnx2i_check_route(dst_addr); 1665 1666 if (!hba) { 1667 rc = -ENOMEM; 1668 goto check_busy; 1669 } 1670 1671 cnic = hba->cnic; 1672 ep = bnx2i_alloc_ep(hba); 1673 if (!ep) { 1674 rc = -ENOMEM; 1675 goto check_busy; 1676 } 1677 bnx2i_ep = ep->dd_data; 1678 1679 mutex_lock(&hba->net_dev_lock); 1680 if (bnx2i_adapter_ready(hba)) { 1681 rc = -EPERM; 1682 goto net_if_down; 1683 } 1684 1685 bnx2i_ep->num_active_cmds = 0; 1686 iscsi_cid = bnx2i_alloc_iscsi_cid(hba); 1687 if (iscsi_cid == -1) { 1688 printk(KERN_ALERT "alloc_ep: unable to allocate iscsi cid\n"); 1689 rc = -ENOMEM; 1690 goto iscsi_cid_err; 1691 } 1692 bnx2i_ep->hba_age = hba->age; 1693 1694 rc = bnx2i_alloc_qp_resc(hba, bnx2i_ep); 1695 if (rc != 0) { 1696 printk(KERN_ALERT "bnx2i: ep_conn, alloc QP resc error\n"); 1697 rc = -ENOMEM; 1698 goto qp_resc_err; 1699 } 1700 1701 bnx2i_ep->ep_iscsi_cid = (u16)iscsi_cid; 1702 bnx2i_ep->state = EP_STATE_OFLD_START; 1703 bnx2i_ep_ofld_list_add(hba, bnx2i_ep); 1704 1705 init_timer(&bnx2i_ep->ofld_timer); 1706 bnx2i_ep->ofld_timer.expires = 2 * HZ + jiffies; 1707 bnx2i_ep->ofld_timer.function = bnx2i_ep_ofld_timer; 1708 bnx2i_ep->ofld_timer.data = (unsigned long) bnx2i_ep; 1709 add_timer(&bnx2i_ep->ofld_timer); 1710 1711 bnx2i_send_conn_ofld_req(hba, bnx2i_ep); 1712 1713 /* Wait for CNIC hardware to setup conn context and return 'cid' */ 1714 wait_event_interruptible(bnx2i_ep->ofld_wait, 1715 bnx2i_ep->state != EP_STATE_OFLD_START); 1716 1717 if (signal_pending(current)) 1718 flush_signals(current); 1719 del_timer_sync(&bnx2i_ep->ofld_timer); 1720 1721 bnx2i_ep_ofld_list_del(hba, bnx2i_ep); 1722 1723 if (bnx2i_ep->state != EP_STATE_OFLD_COMPL) { 1724 rc = -ENOSPC; 1725 goto conn_failed; 1726 } 1727 1728 rc = cnic->cm_create(cnic, CNIC_ULP_ISCSI, bnx2i_ep->ep_cid, 1729 iscsi_cid, &bnx2i_ep->cm_sk, bnx2i_ep); 1730 if (rc) { 1731 rc = -EINVAL; 1732 goto conn_failed; 1733 } 1734 1735 bnx2i_ep->cm_sk->rcv_buf = 256 * 1024; 1736 bnx2i_ep->cm_sk->snd_buf = 256 * 1024; 1737 clear_bit(SK_TCP_TIMESTAMP, &bnx2i_ep->cm_sk->tcp_flags); 1738 1739 memset(&saddr, 0, sizeof(saddr)); 1740 if (dst_addr->sa_family == AF_INET) { 1741 desti = (struct sockaddr_in *) dst_addr; 1742 saddr.remote.v4 = *desti; 1743 saddr.local.v4.sin_family = desti->sin_family; 1744 } else if (dst_addr->sa_family == AF_INET6) { 1745 desti6 = (struct sockaddr_in6 *) dst_addr; 1746 saddr.remote.v6 = *desti6; 1747 saddr.local.v6.sin6_family = desti6->sin6_family; 1748 } 1749 1750 bnx2i_ep->timestamp = jiffies; 1751 bnx2i_ep->state = EP_STATE_CONNECT_START; 1752 if (!test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic)) { 1753 rc = -EINVAL; 1754 goto conn_failed; 1755 } else 1756 rc = cnic->cm_connect(bnx2i_ep->cm_sk, &saddr); 1757 1758 if (rc) 1759 goto release_ep; 1760 1761 if (bnx2i_map_ep_dbell_regs(bnx2i_ep)) 1762 goto release_ep; 1763 mutex_unlock(&hba->net_dev_lock); 1764 return ep; 1765 1766 release_ep: 1767 if (bnx2i_tear_down_conn(hba, bnx2i_ep)) { 1768 mutex_unlock(&hba->net_dev_lock); 1769 return ERR_PTR(rc); 1770 } 1771 conn_failed: 1772 net_if_down: 1773 iscsi_cid_err: 1774 bnx2i_free_qp_resc(hba, bnx2i_ep); 1775 qp_resc_err: 1776 bnx2i_free_ep(ep); 1777 mutex_unlock(&hba->net_dev_lock); 1778 check_busy: 1779 bnx2i_unreg_dev_all(); 1780 return ERR_PTR(rc); 1781 } 1782 1783 1784 /** 1785 * bnx2i_ep_poll - polls for TCP connection establishement 1786 * @ep: TCP connection (endpoint) handle 1787 * @timeout_ms: timeout value in milli secs 1788 * 1789 * polls for TCP connect request to complete 1790 */ 1791 static int bnx2i_ep_poll(struct iscsi_endpoint *ep, int timeout_ms) 1792 { 1793 struct bnx2i_endpoint *bnx2i_ep; 1794 int rc = 0; 1795 1796 bnx2i_ep = ep->dd_data; 1797 if ((bnx2i_ep->state == EP_STATE_IDLE) || 1798 (bnx2i_ep->state == EP_STATE_CONNECT_FAILED) || 1799 (bnx2i_ep->state == EP_STATE_OFLD_FAILED)) 1800 return -1; 1801 if (bnx2i_ep->state == EP_STATE_CONNECT_COMPL) 1802 return 1; 1803 1804 rc = wait_event_interruptible_timeout(bnx2i_ep->ofld_wait, 1805 ((bnx2i_ep->state == 1806 EP_STATE_OFLD_FAILED) || 1807 (bnx2i_ep->state == 1808 EP_STATE_CONNECT_FAILED) || 1809 (bnx2i_ep->state == 1810 EP_STATE_CONNECT_COMPL)), 1811 msecs_to_jiffies(timeout_ms)); 1812 if (!rc || (bnx2i_ep->state == EP_STATE_OFLD_FAILED)) 1813 rc = -1; 1814 1815 if (rc > 0) 1816 return 1; 1817 else if (!rc) 1818 return 0; /* timeout */ 1819 else 1820 return rc; 1821 } 1822 1823 1824 /** 1825 * bnx2i_ep_tcp_conn_active - check EP state transition 1826 * @ep: endpoint pointer 1827 * 1828 * check if underlying TCP connection is active 1829 */ 1830 static int bnx2i_ep_tcp_conn_active(struct bnx2i_endpoint *bnx2i_ep) 1831 { 1832 int ret; 1833 int cnic_dev_10g = 0; 1834 1835 if (test_bit(BNX2I_NX2_DEV_57710, &bnx2i_ep->hba->cnic_dev_type)) 1836 cnic_dev_10g = 1; 1837 1838 switch (bnx2i_ep->state) { 1839 case EP_STATE_CONNECT_START: 1840 case EP_STATE_CLEANUP_FAILED: 1841 case EP_STATE_OFLD_FAILED: 1842 case EP_STATE_DISCONN_TIMEDOUT: 1843 ret = 0; 1844 break; 1845 case EP_STATE_CONNECT_COMPL: 1846 case EP_STATE_ULP_UPDATE_START: 1847 case EP_STATE_ULP_UPDATE_COMPL: 1848 case EP_STATE_TCP_FIN_RCVD: 1849 case EP_STATE_ULP_UPDATE_FAILED: 1850 ret = 1; 1851 break; 1852 case EP_STATE_TCP_RST_RCVD: 1853 ret = 0; 1854 break; 1855 case EP_STATE_CONNECT_FAILED: 1856 if (cnic_dev_10g) 1857 ret = 1; 1858 else 1859 ret = 0; 1860 break; 1861 default: 1862 ret = 0; 1863 } 1864 1865 return ret; 1866 } 1867 1868 1869 /** 1870 * bnx2i_ep_disconnect - executes TCP connection teardown process 1871 * @ep: TCP connection (endpoint) handle 1872 * 1873 * executes TCP connection teardown process 1874 */ 1875 static void bnx2i_ep_disconnect(struct iscsi_endpoint *ep) 1876 { 1877 struct bnx2i_endpoint *bnx2i_ep; 1878 struct bnx2i_conn *bnx2i_conn = NULL; 1879 struct iscsi_session *session = NULL; 1880 struct iscsi_conn *conn; 1881 struct cnic_dev *cnic; 1882 struct bnx2i_hba *hba; 1883 1884 bnx2i_ep = ep->dd_data; 1885 1886 /* driver should not attempt connection cleanup untill TCP_CONNECT 1887 * completes either successfully or fails. Timeout is 9-secs, so 1888 * wait for it to complete 1889 */ 1890 while ((bnx2i_ep->state == EP_STATE_CONNECT_START) && 1891 !time_after(jiffies, bnx2i_ep->timestamp + (12 * HZ))) 1892 msleep(250); 1893 1894 if (bnx2i_ep->conn) { 1895 bnx2i_conn = bnx2i_ep->conn; 1896 conn = bnx2i_conn->cls_conn->dd_data; 1897 session = conn->session; 1898 1899 spin_lock_bh(&session->lock); 1900 bnx2i_conn->is_bound = 0; 1901 spin_unlock_bh(&session->lock); 1902 } 1903 1904 hba = bnx2i_ep->hba; 1905 if (bnx2i_ep->state == EP_STATE_IDLE) 1906 goto return_bnx2i_ep; 1907 cnic = hba->cnic; 1908 1909 mutex_lock(&hba->net_dev_lock); 1910 1911 if (!test_bit(ADAPTER_STATE_UP, &hba->adapter_state)) 1912 goto free_resc; 1913 if (bnx2i_ep->hba_age != hba->age) 1914 goto free_resc; 1915 1916 if (!bnx2i_ep_tcp_conn_active(bnx2i_ep)) 1917 goto destory_conn; 1918 1919 bnx2i_ep->state = EP_STATE_DISCONN_START; 1920 1921 init_timer(&bnx2i_ep->ofld_timer); 1922 bnx2i_ep->ofld_timer.expires = 10*HZ + jiffies; 1923 bnx2i_ep->ofld_timer.function = bnx2i_ep_ofld_timer; 1924 bnx2i_ep->ofld_timer.data = (unsigned long) bnx2i_ep; 1925 add_timer(&bnx2i_ep->ofld_timer); 1926 1927 if (test_bit(BNX2I_CNIC_REGISTERED, &hba->reg_with_cnic)) { 1928 int close = 0; 1929 1930 if (session) { 1931 spin_lock_bh(&session->lock); 1932 if (session->state == ISCSI_STATE_LOGGING_OUT) 1933 close = 1; 1934 spin_unlock_bh(&session->lock); 1935 } 1936 if (close) 1937 cnic->cm_close(bnx2i_ep->cm_sk); 1938 else 1939 cnic->cm_abort(bnx2i_ep->cm_sk); 1940 } else 1941 goto free_resc; 1942 1943 /* wait for option-2 conn teardown */ 1944 wait_event_interruptible(bnx2i_ep->ofld_wait, 1945 bnx2i_ep->state != EP_STATE_DISCONN_START); 1946 1947 if (signal_pending(current)) 1948 flush_signals(current); 1949 del_timer_sync(&bnx2i_ep->ofld_timer); 1950 1951 destory_conn: 1952 if (bnx2i_tear_down_conn(hba, bnx2i_ep)) { 1953 mutex_unlock(&hba->net_dev_lock); 1954 return; 1955 } 1956 free_resc: 1957 mutex_unlock(&hba->net_dev_lock); 1958 bnx2i_free_qp_resc(hba, bnx2i_ep); 1959 return_bnx2i_ep: 1960 if (bnx2i_conn) 1961 bnx2i_conn->ep = NULL; 1962 1963 bnx2i_free_ep(ep); 1964 1965 if (!hba->ofld_conns_active) 1966 bnx2i_unreg_dev_all(); 1967 } 1968 1969 1970 /** 1971 * bnx2i_nl_set_path - ISCSI_UEVENT_PATH_UPDATE user message handler 1972 * @buf: pointer to buffer containing iscsi path message 1973 * 1974 */ 1975 static int bnx2i_nl_set_path(struct Scsi_Host *shost, struct iscsi_path *params) 1976 { 1977 struct bnx2i_hba *hba = iscsi_host_priv(shost); 1978 char *buf = (char *) params; 1979 u16 len = sizeof(*params); 1980 1981 /* handled by cnic driver */ 1982 hba->cnic->iscsi_nl_msg_recv(hba->cnic, ISCSI_UEVENT_PATH_UPDATE, buf, 1983 len); 1984 1985 return 0; 1986 } 1987 1988 1989 /* 1990 * 'Scsi_Host_Template' structure and 'iscsi_tranport' structure template 1991 * used while registering with the scsi host and iSCSI transport module. 1992 */ 1993 static struct scsi_host_template bnx2i_host_template = { 1994 .module = THIS_MODULE, 1995 .name = "Broadcom Offload iSCSI Initiator", 1996 .proc_name = "bnx2i", 1997 .queuecommand = iscsi_queuecommand, 1998 .eh_abort_handler = iscsi_eh_abort, 1999 .eh_device_reset_handler = iscsi_eh_device_reset, 2000 .eh_target_reset_handler = iscsi_eh_target_reset, 2001 .can_queue = 1024, 2002 .max_sectors = 127, 2003 .cmd_per_lun = 32, 2004 .this_id = -1, 2005 .use_clustering = ENABLE_CLUSTERING, 2006 .sg_tablesize = ISCSI_MAX_BDS_PER_CMD, 2007 .shost_attrs = bnx2i_dev_attributes, 2008 }; 2009 2010 struct iscsi_transport bnx2i_iscsi_transport = { 2011 .owner = THIS_MODULE, 2012 .name = "bnx2i", 2013 .caps = CAP_RECOVERY_L0 | CAP_HDRDGST | 2014 CAP_MULTI_R2T | CAP_DATADGST | 2015 CAP_DATA_PATH_OFFLOAD, 2016 .param_mask = ISCSI_MAX_RECV_DLENGTH | 2017 ISCSI_MAX_XMIT_DLENGTH | 2018 ISCSI_HDRDGST_EN | 2019 ISCSI_DATADGST_EN | 2020 ISCSI_INITIAL_R2T_EN | 2021 ISCSI_MAX_R2T | 2022 ISCSI_IMM_DATA_EN | 2023 ISCSI_FIRST_BURST | 2024 ISCSI_MAX_BURST | 2025 ISCSI_PDU_INORDER_EN | 2026 ISCSI_DATASEQ_INORDER_EN | 2027 ISCSI_ERL | 2028 ISCSI_CONN_PORT | 2029 ISCSI_CONN_ADDRESS | 2030 ISCSI_EXP_STATSN | 2031 ISCSI_PERSISTENT_PORT | 2032 ISCSI_PERSISTENT_ADDRESS | 2033 ISCSI_TARGET_NAME | ISCSI_TPGT | 2034 ISCSI_USERNAME | ISCSI_PASSWORD | 2035 ISCSI_USERNAME_IN | ISCSI_PASSWORD_IN | 2036 ISCSI_FAST_ABORT | ISCSI_ABORT_TMO | 2037 ISCSI_LU_RESET_TMO | 2038 ISCSI_PING_TMO | ISCSI_RECV_TMO | 2039 ISCSI_IFACE_NAME | ISCSI_INITIATOR_NAME, 2040 .host_param_mask = ISCSI_HOST_HWADDRESS | ISCSI_HOST_NETDEV_NAME, 2041 .create_session = bnx2i_session_create, 2042 .destroy_session = bnx2i_session_destroy, 2043 .create_conn = bnx2i_conn_create, 2044 .bind_conn = bnx2i_conn_bind, 2045 .destroy_conn = bnx2i_conn_destroy, 2046 .set_param = iscsi_set_param, 2047 .get_conn_param = bnx2i_conn_get_param, 2048 .get_session_param = iscsi_session_get_param, 2049 .get_host_param = bnx2i_host_get_param, 2050 .start_conn = bnx2i_conn_start, 2051 .stop_conn = iscsi_conn_stop, 2052 .send_pdu = iscsi_conn_send_pdu, 2053 .xmit_task = bnx2i_task_xmit, 2054 .get_stats = bnx2i_conn_get_stats, 2055 /* TCP connect - disconnect - option-2 interface calls */ 2056 .ep_connect = bnx2i_ep_connect, 2057 .ep_poll = bnx2i_ep_poll, 2058 .ep_disconnect = bnx2i_ep_disconnect, 2059 .set_path = bnx2i_nl_set_path, 2060 /* Error recovery timeout call */ 2061 .session_recovery_timedout = iscsi_session_recovery_timedout, 2062 .cleanup_task = bnx2i_cleanup_task, 2063 }; 2064