aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/bfa
diff options
context:
space:
mode:
authorKrishna Gudipati <kgudipat@brocade.com>2011-12-20 21:58:32 -0500
committerJames Bottomley <JBottomley@Parallels.com>2012-01-10 18:01:24 -0500
commit5b7db7af522d9f281ff8bf540d2b5cbea2206b27 (patch)
tree7e2b2750a13a5ee9794d1893a0b575419cde95cf /drivers/scsi/bfa
parent8ca2dd87e7f29df99389e9dc41f7a45a35223672 (diff)
[SCSI] bfa: Implement LUN Masking feature using the SCSI Slave Callouts.
This patch re-implements LUN Masking feature using SCSI Slave Callouts. With the new design in the slave_alloc entry point; for each new LUN discovered we check with our internal LUN Masking config whether to expose or to mask this particular LUN. We return -ENXIO (No such device or address) from slave_alloc for the LUNs we don't want to be exposed. We also notify the SCSI mid-layer to do a sequential LUN scan rather than REPORT_LUNS based scan if LUN masking is enabled on our HBA port, since a -ENXIO from any LUN in REPORT_LUNS based scan translates to a scan abort. This patch also handles the dynamic lun masking config change from enable to disable or vice-versa by resetting sdev_bflags of LUN 0 appropriately. Signed-off-by: Krishna Gudipati <kgudipat@brocade.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/bfa')
-rw-r--r--drivers/scsi/bfa/bfad.c2
-rw-r--r--drivers/scsi/bfa/bfad_attr.c2
-rw-r--r--drivers/scsi/bfa/bfad_bsg.c27
-rw-r--r--drivers/scsi/bfa/bfad_drv.h2
-rw-r--r--drivers/scsi/bfa/bfad_im.c56
-rw-r--r--drivers/scsi/bfa/bfad_im.h27
6 files changed, 112 insertions, 4 deletions
diff --git a/drivers/scsi/bfa/bfad.c b/drivers/scsi/bfa/bfad.c
index 66fb72531b34..404fd10ddb21 100644
--- a/drivers/scsi/bfa/bfad.c
+++ b/drivers/scsi/bfa/bfad.c
@@ -674,6 +674,7 @@ bfad_vport_create(struct bfad_s *bfad, u16 vf_id,
674 674
675 spin_lock_irqsave(&bfad->bfad_lock, flags); 675 spin_lock_irqsave(&bfad->bfad_lock, flags);
676 bfa_fcs_vport_start(&vport->fcs_vport); 676 bfa_fcs_vport_start(&vport->fcs_vport);
677 list_add_tail(&vport->list_entry, &bfad->vport_list);
677 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 678 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
678 679
679 return BFA_STATUS_OK; 680 return BFA_STATUS_OK;
@@ -1404,6 +1405,7 @@ bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid)
1404 bfad->ref_count = 0; 1405 bfad->ref_count = 0;
1405 bfad->pport.bfad = bfad; 1406 bfad->pport.bfad = bfad;
1406 INIT_LIST_HEAD(&bfad->pbc_vport_list); 1407 INIT_LIST_HEAD(&bfad->pbc_vport_list);
1408 INIT_LIST_HEAD(&bfad->vport_list);
1407 1409
1408 /* Setup the debugfs node for this bfad */ 1410 /* Setup the debugfs node for this bfad */
1409 if (bfa_debugfs_enable) 1411 if (bfa_debugfs_enable)
diff --git a/drivers/scsi/bfa/bfad_attr.c b/drivers/scsi/bfa/bfad_attr.c
index 9d95844ab463..1938fe0473e9 100644
--- a/drivers/scsi/bfa/bfad_attr.c
+++ b/drivers/scsi/bfa/bfad_attr.c
@@ -491,7 +491,7 @@ bfad_im_vport_delete(struct fc_vport *fc_vport)
491 491
492free_scsi_host: 492free_scsi_host:
493 bfad_scsi_host_free(bfad, im_port); 493 bfad_scsi_host_free(bfad, im_port);
494 494 list_del(&vport->list_entry);
495 kfree(vport); 495 kfree(vport);
496 496
497 return 0; 497 return 0;
diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c
index 06fc00caeb41..530de2b1200a 100644
--- a/drivers/scsi/bfa/bfad_bsg.c
+++ b/drivers/scsi/bfa/bfad_bsg.c
@@ -2394,6 +2394,21 @@ out:
2394 return 0; 2394 return 0;
2395} 2395}
2396 2396
2397/* Function to reset the LUN SCAN mode */
2398static void
2399bfad_iocmd_lunmask_reset_lunscan_mode(struct bfad_s *bfad, int lunmask_cfg)
2400{
2401 struct bfad_im_port_s *pport_im = bfad->pport.im_port;
2402 struct bfad_vport_s *vport = NULL;
2403
2404 /* Set the scsi device LUN SCAN flags for base port */
2405 bfad_reset_sdev_bflags(pport_im, lunmask_cfg);
2406
2407 /* Set the scsi device LUN SCAN flags for the vports */
2408 list_for_each_entry(vport, &bfad->vport_list, list_entry)
2409 bfad_reset_sdev_bflags(vport->drv_port.im_port, lunmask_cfg);
2410}
2411
2397int 2412int
2398bfad_iocmd_lunmask(struct bfad_s *bfad, void *pcmd, unsigned int v_cmd) 2413bfad_iocmd_lunmask(struct bfad_s *bfad, void *pcmd, unsigned int v_cmd)
2399{ 2414{
@@ -2401,11 +2416,17 @@ bfad_iocmd_lunmask(struct bfad_s *bfad, void *pcmd, unsigned int v_cmd)
2401 unsigned long flags; 2416 unsigned long flags;
2402 2417
2403 spin_lock_irqsave(&bfad->bfad_lock, flags); 2418 spin_lock_irqsave(&bfad->bfad_lock, flags);
2404 if (v_cmd == IOCMD_FCPIM_LUNMASK_ENABLE) 2419 if (v_cmd == IOCMD_FCPIM_LUNMASK_ENABLE) {
2405 iocmd->status = bfa_fcpim_lunmask_update(&bfad->bfa, BFA_TRUE); 2420 iocmd->status = bfa_fcpim_lunmask_update(&bfad->bfa, BFA_TRUE);
2406 else if (v_cmd == IOCMD_FCPIM_LUNMASK_DISABLE) 2421 /* Set the LUN Scanning mode to be Sequential scan */
2422 if (iocmd->status == BFA_STATUS_OK)
2423 bfad_iocmd_lunmask_reset_lunscan_mode(bfad, BFA_TRUE);
2424 } else if (v_cmd == IOCMD_FCPIM_LUNMASK_DISABLE) {
2407 iocmd->status = bfa_fcpim_lunmask_update(&bfad->bfa, BFA_FALSE); 2425 iocmd->status = bfa_fcpim_lunmask_update(&bfad->bfa, BFA_FALSE);
2408 else if (v_cmd == IOCMD_FCPIM_LUNMASK_CLEAR) 2426 /* Set the LUN Scanning mode to default REPORT_LUNS scan */
2427 if (iocmd->status == BFA_STATUS_OK)
2428 bfad_iocmd_lunmask_reset_lunscan_mode(bfad, BFA_FALSE);
2429 } else if (v_cmd == IOCMD_FCPIM_LUNMASK_CLEAR)
2409 iocmd->status = bfa_fcpim_lunmask_clear(&bfad->bfa); 2430 iocmd->status = bfa_fcpim_lunmask_clear(&bfad->bfa);
2410 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 2431 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
2411 return 0; 2432 return 0;
diff --git a/drivers/scsi/bfa/bfad_drv.h b/drivers/scsi/bfa/bfad_drv.h
index 5e19a5f820ec..dc5b9d99c450 100644
--- a/drivers/scsi/bfa/bfad_drv.h
+++ b/drivers/scsi/bfa/bfad_drv.h
@@ -43,6 +43,7 @@
43#include <scsi/scsi_transport_fc.h> 43#include <scsi/scsi_transport_fc.h>
44#include <scsi/scsi_transport.h> 44#include <scsi/scsi_transport.h>
45#include <scsi/scsi_bsg_fc.h> 45#include <scsi/scsi_bsg_fc.h>
46#include <scsi/scsi_devinfo.h>
46 47
47#include "bfa_modules.h" 48#include "bfa_modules.h"
48#include "bfa_fcs.h" 49#include "bfa_fcs.h"
@@ -227,6 +228,7 @@ struct bfad_s {
227 struct list_head active_aen_q; 228 struct list_head active_aen_q;
228 struct bfa_aen_entry_s aen_list[BFA_AEN_MAX_ENTRY]; 229 struct bfa_aen_entry_s aen_list[BFA_AEN_MAX_ENTRY];
229 spinlock_t bfad_aen_spinlock; 230 spinlock_t bfad_aen_spinlock;
231 struct list_head vport_list;
230}; 232};
231 233
232/* BFAD state machine events */ 234/* BFAD state machine events */
diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c
index e5db649e8eb7..3153923f5b60 100644
--- a/drivers/scsi/bfa/bfad_im.c
+++ b/drivers/scsi/bfa/bfad_im.c
@@ -918,16 +918,70 @@ bfad_get_itnim(struct bfad_im_port_s *im_port, int id)
918} 918}
919 919
920/* 920/*
921 * Function is invoked from the SCSI Host Template slave_alloc() entry point.
922 * Has the logic to query the LUN Mask database to check if this LUN needs to
923 * be made visible to the SCSI mid-layer or not.
924 *
925 * Returns BFA_STATUS_OK if this LUN needs to be added to the OS stack.
926 * Returns -ENXIO to notify SCSI mid-layer to not add this LUN to the OS stack.
927 */
928static int
929bfad_im_check_if_make_lun_visible(struct scsi_device *sdev,
930 struct fc_rport *rport)
931{
932 struct bfad_itnim_data_s *itnim_data =
933 (struct bfad_itnim_data_s *) rport->dd_data;
934 struct bfa_s *bfa = itnim_data->itnim->bfa_itnim->bfa;
935 struct bfa_rport_s *bfa_rport = itnim_data->itnim->bfa_itnim->rport;
936 struct bfa_lun_mask_s *lun_list = bfa_get_lun_mask_list(bfa);
937 int i = 0, ret = -ENXIO;
938
939 for (i = 0; i < MAX_LUN_MASK_CFG; i++) {
940 if (lun_list[i].state == BFA_IOIM_LUN_MASK_ACTIVE &&
941 scsilun_to_int(&lun_list[i].lun) == sdev->lun &&
942 lun_list[i].rp_tag == bfa_rport->rport_tag &&
943 lun_list[i].lp_tag == (u8)bfa_rport->rport_info.lp_tag) {
944 ret = BFA_STATUS_OK;
945 break;
946 }
947 }
948 return ret;
949}
950
951/*
921 * Scsi_Host template entry slave_alloc 952 * Scsi_Host template entry slave_alloc
922 */ 953 */
923static int 954static int
924bfad_im_slave_alloc(struct scsi_device *sdev) 955bfad_im_slave_alloc(struct scsi_device *sdev)
925{ 956{
926 struct fc_rport *rport = starget_to_rport(scsi_target(sdev)); 957 struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
958 struct bfad_itnim_data_s *itnim_data =
959 (struct bfad_itnim_data_s *) rport->dd_data;
960 struct bfa_s *bfa = itnim_data->itnim->bfa_itnim->bfa;
927 961
928 if (!rport || fc_remote_port_chkready(rport)) 962 if (!rport || fc_remote_port_chkready(rport))
929 return -ENXIO; 963 return -ENXIO;
930 964
965 if (bfa_get_lun_mask_status(bfa) == BFA_LUNMASK_ENABLED) {
966 /*
967 * We should not mask LUN 0 - since this will translate
968 * to no LUN / TARGET for SCSI ml resulting no scan.
969 */
970 if (sdev->lun == 0) {
971 sdev->sdev_bflags |= BLIST_NOREPORTLUN |
972 BLIST_SPARSELUN;
973 goto done;
974 }
975
976 /*
977 * Query LUN Mask configuration - to expose this LUN
978 * to the SCSI mid-layer or to mask it.
979 */
980 if (bfad_im_check_if_make_lun_visible(sdev, rport) !=
981 BFA_STATUS_OK)
982 return -ENXIO;
983 }
984done:
931 sdev->hostdata = rport->dd_data; 985 sdev->hostdata = rport->dd_data;
932 986
933 return 0; 987 return 0;
@@ -1037,6 +1091,8 @@ bfad_im_fc_rport_add(struct bfad_im_port_s *im_port, struct bfad_itnim_s *itnim)
1037 && (fc_rport->scsi_target_id < MAX_FCP_TARGET)) 1091 && (fc_rport->scsi_target_id < MAX_FCP_TARGET))
1038 itnim->scsi_tgt_id = fc_rport->scsi_target_id; 1092 itnim->scsi_tgt_id = fc_rport->scsi_target_id;
1039 1093
1094 itnim->channel = fc_rport->channel;
1095
1040 return; 1096 return;
1041} 1097}
1042 1098
diff --git a/drivers/scsi/bfa/bfad_im.h b/drivers/scsi/bfa/bfad_im.h
index 004b6cf848d9..0814367ef101 100644
--- a/drivers/scsi/bfa/bfad_im.h
+++ b/drivers/scsi/bfa/bfad_im.h
@@ -91,6 +91,7 @@ struct bfad_itnim_s {
91 struct fc_rport *fc_rport; 91 struct fc_rport *fc_rport;
92 struct bfa_itnim_s *bfa_itnim; 92 struct bfa_itnim_s *bfa_itnim;
93 u16 scsi_tgt_id; 93 u16 scsi_tgt_id;
94 u16 channel;
94 u16 queue_work; 95 u16 queue_work;
95 unsigned long last_ramp_up_time; 96 unsigned long last_ramp_up_time;
96 unsigned long last_queue_full_time; 97 unsigned long last_queue_full_time;
@@ -166,4 +167,30 @@ irqreturn_t bfad_intx(int irq, void *dev_id);
166int bfad_im_bsg_request(struct fc_bsg_job *job); 167int bfad_im_bsg_request(struct fc_bsg_job *job);
167int bfad_im_bsg_timeout(struct fc_bsg_job *job); 168int bfad_im_bsg_timeout(struct fc_bsg_job *job);
168 169
170/*
171 * Macro to set the SCSI device sdev_bflags - sdev_bflags are used by the
172 * SCSI mid-layer to choose LUN Scanning mode REPORT_LUNS vs. Sequential Scan
173 *
174 * Internally iterate's over all the ITNIM's part of the im_port & set's the
175 * sdev_bflags for the scsi_device associated with LUN #0.
176 */
177#define bfad_reset_sdev_bflags(__im_port, __lunmask_cfg) do { \
178 struct scsi_device *__sdev = NULL; \
179 struct bfad_itnim_s *__itnim = NULL; \
180 u32 scan_flags = BLIST_NOREPORTLUN | BLIST_SPARSELUN; \
181 list_for_each_entry(__itnim, &((__im_port)->itnim_mapped_list), \
182 list_entry) { \
183 __sdev = scsi_device_lookup((__im_port)->shost, \
184 __itnim->channel, \
185 __itnim->scsi_tgt_id, 0); \
186 if (__sdev) { \
187 if ((__lunmask_cfg) == BFA_TRUE) \
188 __sdev->sdev_bflags |= scan_flags; \
189 else \
190 __sdev->sdev_bflags &= ~scan_flags; \
191 scsi_device_put(__sdev); \
192 } \
193 } \
194} while (0)
195
169#endif 196#endif