diff options
Diffstat (limited to 'drivers/scsi/fnic/fnic_scsi.c')
-rw-r--r-- | drivers/scsi/fnic/fnic_scsi.c | 96 |
1 files changed, 38 insertions, 58 deletions
diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c index bfc996971b81..65a39b0f6dc2 100644 --- a/drivers/scsi/fnic/fnic_scsi.c +++ b/drivers/scsi/fnic/fnic_scsi.c | |||
@@ -174,6 +174,9 @@ int fnic_fw_reset_handler(struct fnic *fnic) | |||
174 | int ret = 0; | 174 | int ret = 0; |
175 | unsigned long flags; | 175 | unsigned long flags; |
176 | 176 | ||
177 | skb_queue_purge(&fnic->frame_queue); | ||
178 | skb_queue_purge(&fnic->tx_queue); | ||
179 | |||
177 | spin_lock_irqsave(&fnic->wq_copy_lock[0], flags); | 180 | spin_lock_irqsave(&fnic->wq_copy_lock[0], flags); |
178 | 181 | ||
179 | if (vnic_wq_copy_desc_avail(wq) <= fnic->wq_copy_desc_low[0]) | 182 | if (vnic_wq_copy_desc_avail(wq) <= fnic->wq_copy_desc_low[0]) |
@@ -200,9 +203,11 @@ int fnic_fw_reset_handler(struct fnic *fnic) | |||
200 | * fnic_flogi_reg_handler | 203 | * fnic_flogi_reg_handler |
201 | * Routine to send flogi register msg to fw | 204 | * Routine to send flogi register msg to fw |
202 | */ | 205 | */ |
203 | int fnic_flogi_reg_handler(struct fnic *fnic) | 206 | int fnic_flogi_reg_handler(struct fnic *fnic, u32 fc_id) |
204 | { | 207 | { |
205 | struct vnic_wq_copy *wq = &fnic->wq_copy[0]; | 208 | struct vnic_wq_copy *wq = &fnic->wq_copy[0]; |
209 | enum fcpio_flogi_reg_format_type format; | ||
210 | struct fc_lport *lp = fnic->lport; | ||
206 | u8 gw_mac[ETH_ALEN]; | 211 | u8 gw_mac[ETH_ALEN]; |
207 | int ret = 0; | 212 | int ret = 0; |
208 | unsigned long flags; | 213 | unsigned long flags; |
@@ -217,23 +222,32 @@ int fnic_flogi_reg_handler(struct fnic *fnic) | |||
217 | goto flogi_reg_ioreq_end; | 222 | goto flogi_reg_ioreq_end; |
218 | } | 223 | } |
219 | 224 | ||
220 | if (fnic->fcoui_mode) | 225 | if (fnic->ctlr.map_dest) { |
221 | memset(gw_mac, 0xff, ETH_ALEN); | 226 | memset(gw_mac, 0xff, ETH_ALEN); |
222 | else | 227 | format = FCPIO_FLOGI_REG_DEF_DEST; |
223 | memcpy(gw_mac, fnic->dest_addr, ETH_ALEN); | 228 | } else { |
229 | memcpy(gw_mac, fnic->ctlr.dest_addr, ETH_ALEN); | ||
230 | format = FCPIO_FLOGI_REG_GW_DEST; | ||
231 | } | ||
224 | 232 | ||
225 | fnic_queue_wq_copy_desc_flogi_reg(wq, SCSI_NO_TAG, | 233 | if ((fnic->config.flags & VFCF_FIP_CAPABLE) && !fnic->ctlr.map_dest) { |
226 | FCPIO_FLOGI_REG_GW_DEST, | 234 | fnic_queue_wq_copy_desc_fip_reg(wq, SCSI_NO_TAG, |
227 | fnic->s_id, | 235 | fc_id, gw_mac, |
228 | gw_mac); | 236 | fnic->data_src_addr, |
237 | lp->r_a_tov, lp->e_d_tov); | ||
238 | FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, | ||
239 | "FLOGI FIP reg issued fcid %x src %pM dest %pM\n", | ||
240 | fc_id, fnic->data_src_addr, gw_mac); | ||
241 | } else { | ||
242 | fnic_queue_wq_copy_desc_flogi_reg(wq, SCSI_NO_TAG, | ||
243 | format, fc_id, gw_mac); | ||
244 | FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, | ||
245 | "FLOGI reg issued fcid %x map %d dest %pM\n", | ||
246 | fc_id, fnic->ctlr.map_dest, gw_mac); | ||
247 | } | ||
229 | 248 | ||
230 | flogi_reg_ioreq_end: | 249 | flogi_reg_ioreq_end: |
231 | spin_unlock_irqrestore(&fnic->wq_copy_lock[0], flags); | 250 | spin_unlock_irqrestore(&fnic->wq_copy_lock[0], flags); |
232 | |||
233 | if (!ret) | ||
234 | FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, | ||
235 | "flog reg issued\n"); | ||
236 | |||
237 | return ret; | 251 | return ret; |
238 | } | 252 | } |
239 | 253 | ||
@@ -319,7 +333,8 @@ static inline int fnic_queue_wq_copy_desc(struct fnic *fnic, | |||
319 | 0, /* scsi cmd ref, always 0 */ | 333 | 0, /* scsi cmd ref, always 0 */ |
320 | pri_tag, /* scsi pri and tag */ | 334 | pri_tag, /* scsi pri and tag */ |
321 | flags, /* command flags */ | 335 | flags, /* command flags */ |
322 | sc->cmnd, scsi_bufflen(sc), | 336 | sc->cmnd, sc->cmd_len, |
337 | scsi_bufflen(sc), | ||
323 | fc_lun.scsi_lun, io_req->port_id, | 338 | fc_lun.scsi_lun, io_req->port_id, |
324 | rport->maxframe_size, rp->r_a_tov, | 339 | rport->maxframe_size, rp->r_a_tov, |
325 | rp->e_d_tov); | 340 | rp->e_d_tov); |
@@ -452,7 +467,6 @@ static int fnic_fcpio_fw_reset_cmpl_handler(struct fnic *fnic, | |||
452 | u8 hdr_status; | 467 | u8 hdr_status; |
453 | struct fcpio_tag tag; | 468 | struct fcpio_tag tag; |
454 | int ret = 0; | 469 | int ret = 0; |
455 | struct fc_frame *flogi; | ||
456 | unsigned long flags; | 470 | unsigned long flags; |
457 | 471 | ||
458 | fcpio_header_dec(&desc->hdr, &type, &hdr_status, &tag); | 472 | fcpio_header_dec(&desc->hdr, &type, &hdr_status, &tag); |
@@ -462,9 +476,6 @@ static int fnic_fcpio_fw_reset_cmpl_handler(struct fnic *fnic, | |||
462 | 476 | ||
463 | spin_lock_irqsave(&fnic->fnic_lock, flags); | 477 | spin_lock_irqsave(&fnic->fnic_lock, flags); |
464 | 478 | ||
465 | flogi = fnic->flogi; | ||
466 | fnic->flogi = NULL; | ||
467 | |||
468 | /* fnic should be in FC_TRANS_ETH_MODE */ | 479 | /* fnic should be in FC_TRANS_ETH_MODE */ |
469 | if (fnic->state == FNIC_IN_FC_TRANS_ETH_MODE) { | 480 | if (fnic->state == FNIC_IN_FC_TRANS_ETH_MODE) { |
470 | /* Check status of reset completion */ | 481 | /* Check status of reset completion */ |
@@ -505,17 +516,14 @@ static int fnic_fcpio_fw_reset_cmpl_handler(struct fnic *fnic, | |||
505 | * free the flogi frame. Else, send it out | 516 | * free the flogi frame. Else, send it out |
506 | */ | 517 | */ |
507 | if (fnic->remove_wait || ret) { | 518 | if (fnic->remove_wait || ret) { |
508 | fnic->flogi_oxid = FC_XID_UNKNOWN; | ||
509 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); | 519 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); |
510 | if (flogi) | 520 | skb_queue_purge(&fnic->tx_queue); |
511 | dev_kfree_skb_irq(fp_skb(flogi)); | ||
512 | goto reset_cmpl_handler_end; | 521 | goto reset_cmpl_handler_end; |
513 | } | 522 | } |
514 | 523 | ||
515 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); | 524 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); |
516 | 525 | ||
517 | if (flogi) | 526 | fnic_flush_tx(fnic); |
518 | ret = fnic_send_frame(fnic, flogi); | ||
519 | 527 | ||
520 | reset_cmpl_handler_end: | 528 | reset_cmpl_handler_end: |
521 | return ret; | 529 | return ret; |
@@ -532,18 +540,13 @@ static int fnic_fcpio_flogi_reg_cmpl_handler(struct fnic *fnic, | |||
532 | u8 hdr_status; | 540 | u8 hdr_status; |
533 | struct fcpio_tag tag; | 541 | struct fcpio_tag tag; |
534 | int ret = 0; | 542 | int ret = 0; |
535 | struct fc_frame *flogi_resp = NULL; | ||
536 | unsigned long flags; | 543 | unsigned long flags; |
537 | struct sk_buff *skb; | ||
538 | 544 | ||
539 | fcpio_header_dec(&desc->hdr, &type, &hdr_status, &tag); | 545 | fcpio_header_dec(&desc->hdr, &type, &hdr_status, &tag); |
540 | 546 | ||
541 | /* Update fnic state based on status of flogi reg completion */ | 547 | /* Update fnic state based on status of flogi reg completion */ |
542 | spin_lock_irqsave(&fnic->fnic_lock, flags); | 548 | spin_lock_irqsave(&fnic->fnic_lock, flags); |
543 | 549 | ||
544 | flogi_resp = fnic->flogi_resp; | ||
545 | fnic->flogi_resp = NULL; | ||
546 | |||
547 | if (fnic->state == FNIC_IN_ETH_TRANS_FC_MODE) { | 550 | if (fnic->state == FNIC_IN_ETH_TRANS_FC_MODE) { |
548 | 551 | ||
549 | /* Check flogi registration completion status */ | 552 | /* Check flogi registration completion status */ |
@@ -567,25 +570,17 @@ static int fnic_fcpio_flogi_reg_cmpl_handler(struct fnic *fnic, | |||
567 | ret = -1; | 570 | ret = -1; |
568 | } | 571 | } |
569 | 572 | ||
570 | /* Successful flogi reg cmpl, pass frame to LibFC */ | 573 | if (!ret) { |
571 | if (!ret && flogi_resp) { | ||
572 | if (fnic->stop_rx_link_events) { | 574 | if (fnic->stop_rx_link_events) { |
573 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); | 575 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); |
574 | goto reg_cmpl_handler_end; | 576 | goto reg_cmpl_handler_end; |
575 | } | 577 | } |
576 | skb = (struct sk_buff *)flogi_resp; | ||
577 | /* Use fr_flags to indicate whether flogi resp or not */ | ||
578 | fr_flags(flogi_resp) = 1; | ||
579 | fr_dev(flogi_resp) = fnic->lport; | ||
580 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); | 578 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); |
581 | 579 | ||
582 | skb_queue_tail(&fnic->frame_queue, skb); | 580 | fnic_flush_tx(fnic); |
583 | queue_work(fnic_event_queue, &fnic->frame_work); | 581 | queue_work(fnic_event_queue, &fnic->frame_work); |
584 | |||
585 | } else { | 582 | } else { |
586 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); | 583 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); |
587 | if (flogi_resp) | ||
588 | dev_kfree_skb_irq(fp_skb(flogi_resp)); | ||
589 | } | 584 | } |
590 | 585 | ||
591 | reg_cmpl_handler_end: | 586 | reg_cmpl_handler_end: |
@@ -907,6 +902,7 @@ static int fnic_fcpio_cmpl_handler(struct vnic_dev *vdev, | |||
907 | break; | 902 | break; |
908 | 903 | ||
909 | case FCPIO_FLOGI_REG_CMPL: /* fw completed flogi_reg */ | 904 | case FCPIO_FLOGI_REG_CMPL: /* fw completed flogi_reg */ |
905 | case FCPIO_FLOGI_FIP_REG_CMPL: /* fw completed flogi_fip_reg */ | ||
910 | ret = fnic_fcpio_flogi_reg_cmpl_handler(fnic, desc); | 906 | ret = fnic_fcpio_flogi_reg_cmpl_handler(fnic, desc); |
911 | break; | 907 | break; |
912 | 908 | ||
@@ -1224,22 +1220,6 @@ void fnic_terminate_rport_io(struct fc_rport *rport) | |||
1224 | 1220 | ||
1225 | } | 1221 | } |
1226 | 1222 | ||
1227 | static void fnic_block_error_handler(struct scsi_cmnd *sc) | ||
1228 | { | ||
1229 | struct Scsi_Host *shost = sc->device->host; | ||
1230 | struct fc_rport *rport = starget_to_rport(scsi_target(sc->device)); | ||
1231 | unsigned long flags; | ||
1232 | |||
1233 | spin_lock_irqsave(shost->host_lock, flags); | ||
1234 | while (rport->port_state == FC_PORTSTATE_BLOCKED) { | ||
1235 | spin_unlock_irqrestore(shost->host_lock, flags); | ||
1236 | msleep(1000); | ||
1237 | spin_lock_irqsave(shost->host_lock, flags); | ||
1238 | } | ||
1239 | spin_unlock_irqrestore(shost->host_lock, flags); | ||
1240 | |||
1241 | } | ||
1242 | |||
1243 | /* | 1223 | /* |
1244 | * This function is exported to SCSI for sending abort cmnds. | 1224 | * This function is exported to SCSI for sending abort cmnds. |
1245 | * A SCSI IO is represented by a io_req in the driver. | 1225 | * A SCSI IO is represented by a io_req in the driver. |
@@ -1259,7 +1239,7 @@ int fnic_abort_cmd(struct scsi_cmnd *sc) | |||
1259 | DECLARE_COMPLETION_ONSTACK(tm_done); | 1239 | DECLARE_COMPLETION_ONSTACK(tm_done); |
1260 | 1240 | ||
1261 | /* Wait for rport to unblock */ | 1241 | /* Wait for rport to unblock */ |
1262 | fnic_block_error_handler(sc); | 1242 | fc_block_scsi_eh(sc); |
1263 | 1243 | ||
1264 | /* Get local-port, check ready and link up */ | 1244 | /* Get local-port, check ready and link up */ |
1265 | lp = shost_priv(sc->device->host); | 1245 | lp = shost_priv(sc->device->host); |
@@ -1541,7 +1521,7 @@ int fnic_device_reset(struct scsi_cmnd *sc) | |||
1541 | DECLARE_COMPLETION_ONSTACK(tm_done); | 1521 | DECLARE_COMPLETION_ONSTACK(tm_done); |
1542 | 1522 | ||
1543 | /* Wait for rport to unblock */ | 1523 | /* Wait for rport to unblock */ |
1544 | fnic_block_error_handler(sc); | 1524 | fc_block_scsi_eh(sc); |
1545 | 1525 | ||
1546 | /* Get local-port, check ready and link up */ | 1526 | /* Get local-port, check ready and link up */ |
1547 | lp = shost_priv(sc->device->host); | 1527 | lp = shost_priv(sc->device->host); |
@@ -1762,7 +1742,7 @@ void fnic_scsi_abort_io(struct fc_lport *lp) | |||
1762 | fnic->remove_wait = &remove_wait; | 1742 | fnic->remove_wait = &remove_wait; |
1763 | old_state = fnic->state; | 1743 | old_state = fnic->state; |
1764 | fnic->state = FNIC_IN_FC_TRANS_ETH_MODE; | 1744 | fnic->state = FNIC_IN_FC_TRANS_ETH_MODE; |
1765 | vnic_dev_del_addr(fnic->vdev, fnic->data_src_addr); | 1745 | fnic_update_mac_locked(fnic, fnic->ctlr.ctl_src_addr); |
1766 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); | 1746 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); |
1767 | 1747 | ||
1768 | err = fnic_fw_reset_handler(fnic); | 1748 | err = fnic_fw_reset_handler(fnic); |
@@ -1802,7 +1782,7 @@ void fnic_scsi_cleanup(struct fc_lport *lp) | |||
1802 | spin_lock_irqsave(&fnic->fnic_lock, flags); | 1782 | spin_lock_irqsave(&fnic->fnic_lock, flags); |
1803 | old_state = fnic->state; | 1783 | old_state = fnic->state; |
1804 | fnic->state = FNIC_IN_FC_TRANS_ETH_MODE; | 1784 | fnic->state = FNIC_IN_FC_TRANS_ETH_MODE; |
1805 | vnic_dev_del_addr(fnic->vdev, fnic->data_src_addr); | 1785 | fnic_update_mac_locked(fnic, fnic->ctlr.ctl_src_addr); |
1806 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); | 1786 | spin_unlock_irqrestore(&fnic->fnic_lock, flags); |
1807 | 1787 | ||
1808 | if (fnic_fw_reset_handler(fnic)) { | 1788 | if (fnic_fw_reset_handler(fnic)) { |