On Tuesday, June 11, 2024 11:45 PM, Hannes Reinecke <hare@xxxxxxx> wrote: > > On 6/10/24 23:50, Karan Tilak Kumar wrote: > > Add support for Fabric-Device Management Interface > > (FDMI) by introducing PCI device IDs for Cisco Hardware. > > Introduce a module parameter to enable/disable FDMI support. > > Integrate support for FDMI. > > > > Reviewed-by: Sesidhar Baddela <sebaddel@xxxxxxxxx> > > Reviewed-by: Arulprabhu Ponnusamy <arulponn@xxxxxxxxx> > > Reviewed-by: Gian Carlo Boffa <gcboffa@xxxxxxxxx> > > Signed-off-by: Karan Tilak Kumar <kartilak@xxxxxxxxx> > > --- > > drivers/scsi/fnic/Makefile | 3 +- > > drivers/scsi/fnic/fdls_disc.c | 281 ++++++++++++++++++++++ > > drivers/scsi/fnic/fnic.h | 72 ++++++ > > drivers/scsi/fnic/fnic_fdls.h | 2 +- > > drivers/scsi/fnic/fnic_main.c | 26 ++ > > drivers/scsi/fnic/fnic_pci_subsys_devid.c | 133 ++++++++++ > > 6 files changed, 515 insertions(+), 2 deletions(-) > > create mode 100644 drivers/scsi/fnic/fnic_pci_subsys_devid.c > > > > + FNIC_SET_OX_ID(fchdr, FNIC_PLOGI_FDMI_OXID); > > Static oxids again. We are evaluating modifying this to pool based OXIDs in the next version. > > + err = vnic_dev_fw_info(fnic->vdev, &fw_info); > > + if (!err) { > > + snprintf(fdmi_rhba.serial_num, sizeof(fdmi_rhba.serial_num) - 1, > > + "%s", fw_info->hw_serial_number); > > + snprintf(fdmi_rhba.hardware_ver, > > + sizeof(fdmi_rhba.hardware_ver) - 1, "%s", > > + fw_info->hw_version); > > + strscpy(fdmi_rhba.firmware_ver, fw_info->fw_version, > > + sizeof(fdmi_rhba.firmware_ver) - 1); > > It turns out to be _really_ useful if host-specific information (like the hostname) is included in the FDMI information. > Especially if you want to troubleshoot fabric setups, and validate the physical setup against the logical setup. > There is a function 'fc_system_hostname' for doing exactly this ... Thanks for the pointer, Hannes. Sure. I'll include this change in the next version. > Please use the standard definitions from scsi_transport_fc.h Sure. I'll do that. Thanks. > > > + fdmi_rpa.supported_speed = htonl(port_speed_bm); > > + fdmi_rpa.current_speed = htonl(port_speed_bm); > > + fdmi_rpa.fc4_type[2] = 1; > > + snprintf(fdmi_rpa.os_name, sizeof(fdmi_rpa.os_name) - 1, "host%d", > > + fnic->lport->host->host_no); > > + snprintf(fdmi_rpa.host_name, sizeof(fdmi_rpa.host_name) - 1, "%s", > > + utsname()->nodename); > > + fnic_send_fcoe_frame(iport, &fdmi_rpa, sizeof(struct > > +fc_fdmi_rpa_s)); } > > + > > void fdls_fabric_timer_callback(struct timer_list *t) > > { > > struct fnic_fdls_fabric_s *fabric = from_timer(fabric, t, > > retry_timer); @@ -1205,6 +1384,23 @@ void fdls_fabric_timer_callback(struct timer_list *t) > > spin_unlock_irqrestore(&fnic->fnic_lock, flags); > > } > > > > +void fdls_fdmi_timer_callback(struct timer_list *t) { > > + struct fnic_fdls_fabric_s *fabric = from_timer(fabric, t, fdmi_timer); > > + struct fnic_iport_s *iport = > > + container_of(fabric, struct fnic_iport_s, fabric); > > + struct fnic *fnic = iport->fnic; > > + > > + if (iport->fabric.fdmi_retry < 7) { > > + iport->fabric.fdmi_retry++; > > + FNIC_FCS_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num, > > + "retry fdmi timer %d", iport->fabric.fdmi_retry); > > + fdls_send_fdmi_plogi(iport); > > + } else { > > + iport->fabric.fdmi_pending = 0; > > + } > > +} > > + > > static void fdls_send_delete_tport_msg(struct fnic_tport_s *tport) > > { > > struct fnic_iport_s *iport = (struct fnic_iport_s *) tport->iport; > > @@ -1360,6 +1556,15 @@ static void fnic_fdls_start_plogi(struct fnic_iport_s *iport) > > fdls_send_fabric_plogi(iport); > > fdls_set_state((&iport->fabric), FDLS_STATE_FABRIC_PLOGI); > > iport->fabric.flags &= ~FNIC_FDLS_FABRIC_ABORT_ISSUED; > > + > > + if ((fnic_fdmi_support == 1) && (!(iport->flags & FNIC_FDMI_ACTIVE))) { > > + /* we can do FDMI at the same time */ > > + iport->fabric.fdmi_retry = 0; > > + timer_setup(&iport->fabric.fdmi_timer, fdls_fdmi_timer_callback, > > + 0); > > + fdls_send_fdmi_plogi(iport); > > + iport->flags |= FNIC_FDMI_ACTIVE; > > + } > > } > > > > static void > > @@ -2440,6 +2645,69 @@ fdls_process_fabric_plogi_rsp(struct fnic_iport_s *iport, > > } > > } > > > > +static void fdls_process_fdmi_plogi_rsp(struct fnic_iport_s *iport, > > + struct fc_hdr_s *fchdr) > > +{ > > + struct fc_els_s *plogi_rsp = (struct fc_els_s *) fchdr; > > + struct fc_els_reject_s *els_rjt = (struct fc_els_reject_s *) fchdr; > > + struct fnic *fnic = iport->fnic; > > + u64 fdmi_tov; > > + > > + if (ntoh24(fchdr->sid) == 0XFFFFFA) { > > + del_timer_sync(&iport->fabric.fdmi_timer); > > + iport->fabric.fdmi_pending = 0; > > + switch (plogi_rsp->command) { > > + case FC_LS_ACC: > > + FNIC_FCS_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num, > > + "FDLS process fdmi PLOGI response status: FC_LS_ACC\n"); > > + FNIC_FCS_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num, > > + "Sending fdmi registration for port 0x%x\n", > > + iport->fcid); > > + > > + fdls_fdmi_register_hba(iport); > > + fdls_fdmi_register_pa(iport); > > + fdmi_tov = jiffies + msecs_to_jiffies(5000); > > + mod_timer(&iport->fabric.fdmi_timer, round_jiffies(fdmi_tov)); > > + iport->fabric.fdmi_pending = 2; > > + break; > > + case FC_LS_REJ: > > + FNIC_FCS_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num, > > + "Fabric FDMI PLOGI returned FC_LS_REJ reason: 0x%x", > > + els_rjt->reason_code); > > + > > + if (((els_rjt->reason_code == FC_ELS_RJT_LOGICAL_BUSY) > > + || (els_rjt->reason_code == FC_ELS_RJT_BUSY)) > > + && (iport->fabric.fdmi_retry < 7)) { > > + iport->fabric.fdmi_retry++; > > + fdls_send_fdmi_plogi(iport); > > + } > > + break; > > + default: > > + break; > > + } > > + } > > +} > > + > > +static void fdls_process_fdmi_reg_ack(struct fnic_iport_s *iport, > > + struct fc_hdr_s *fchdr) > > +{ > > + struct fnic *fnic = iport->fnic; > > + > > + if (iport->fabric.fdmi_pending > 0) { > > + iport->fabric.fdmi_pending--; > > + FNIC_FCS_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num, > > + "iport fcid: 0x%x: Received FDMI registration ack\n", > > + iport->fcid); > > + > > + if (iport->fabric.fdmi_pending == 0) { > > + del_timer_sync(&iport->fabric.fdmi_timer); > > + FNIC_FCS_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num, > > + "iport fcid: 0x%x: Canceling FDMI timer\n", > > + iport->fcid); > > + } > > + } > > +} > > + > > static void > > fdls_process_fabric_abts_rsp(struct fnic_iport_s *iport, > > struct fc_hdr_s *fchdr) > > @@ -3367,6 +3635,12 @@ fnic_fdls_validate_and_get_frame_type(struct fnic_iport_s *iport, > > } > > return FNIC_FABRIC_PLOGI_RSP; > > > > + case FNIC_PLOGI_FDMI_OXID: > > + return FNIC_FDMI_PLOGI_RSP; > > + case FNIC_FDMI_REG_HBA_OXID: > > + case FNIC_FDMI_RPA_OXID: > > + return FNIC_FDMI_RSP; > > + > > case FNIC_SCR_REQ_OXID: > > if (type == FC_LS_ACC) { > > if ((s_id != FC_FABRIC_CONTROLLER) @@ -3447,6 +3721,9 @@ void > > fnic_fdls_recv_frame(struct fnic_iport_s *iport, void *rx_frame, > > case FNIC_FABRIC_PLOGI_RSP: > > fdls_process_fabric_plogi_rsp(iport, fchdr); > > break; > > + case FNIC_FDMI_PLOGI_RSP: > > + fdls_process_fdmi_plogi_rsp(iport, fchdr); > > + break; > > case FNIC_FABRIC_RPN_RSP: > > fdls_process_rpn_id_rsp(iport, fchdr); > > break; > > @@ -3514,9 +3791,13 @@ void fnic_fdls_recv_frame(struct fnic_iport_s *iport, void *rx_frame, > > case FNIC_ELS_RLS: > > fdls_process_rls_req(iport, fchdr); > > break; > > + case FNIC_FDMI_RSP: > > + fdls_process_fdmi_reg_ack(iport, fchdr); > > + break; > > default: > > FNIC_FCS_DBG(KERN_INFO, fnic->lport->host, fnic->fnic_num, > > "Received unknown FCoE frame of len: %d. Dropping frame", len); > > break; > > } > > } > > + > > diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h index > > 92cd17efa40f..7d7009197dbc 100644 > > --- a/drivers/scsi/fnic/fnic.h > > +++ b/drivers/scsi/fnic/fnic.h > > @@ -82,6 +82,72 @@ > > /* Retry supported by rport (returned by PRLI service parameters) */ > > #define FNIC_FC_RP_FLAGS_RETRY 0x1 > > > > +/* Cisco vendor id */ > > +#define PCI_VENDOR_ID_CISCO 0x1137 > > +#define PCI_DEVICE_ID_CISCO_VIC_FC 0x0045 /* fc vnic */ > > + > > +/* sereno pcie switch */ > > +#define PCI_DEVICE_ID_CISCO_SERENO 0x004e > > +#define PCI_DEVICE_ID_CISCO_CRUZ 0x007a /* Cruz */ > > +#define PCI_DEVICE_ID_CISCO_BODEGA 0x0131 /* Bodega */ > > +#define PCI_DEVICE_ID_CISCO_BEVERLY 0x025f /* Beverly */ > > + > > +/* Sereno */ > > +#define PCI_SUBDEVICE_ID_CISCO_VASONA 0x004f /* vasona mezz */ > > +#define PCI_SUBDEVICE_ID_CISCO_COTATI 0x0084 /* cotati mlom */ > > +#define PCI_SUBDEVICE_ID_CISCO_LEXINGTON 0x0085 /* lexington pcie */ > > +#define PCI_SUBDEVICE_ID_CISCO_ICEHOUSE 0x00cd /* Icehouse */ > > +#define PCI_SUBDEVICE_ID_CISCO_KIRKWOODLAKE 0x00ce /* KirkwoodLake pcie */ > > +#define PCI_SUBDEVICE_ID_CISCO_SUSANVILLE 0x012e /* Susanville MLOM */ > > +#define PCI_SUBDEVICE_ID_CISCO_TORRANCE 0x0139 /* Torrance MLOM */ > > + > > +/* Cruz */ > > +#define PCI_SUBDEVICE_ID_CISCO_CALISTOGA 0x012c /* Calistoga MLOM */ > > +#define PCI_SUBDEVICE_ID_CISCO_MOUNTAINVIEW 0x0137 /* Cruz Mezz */ > > +/* Cruz MountTian SIOC */ > > +#define PCI_SUBDEVICE_ID_CISCO_MOUNTTIAN 0x014b > > +#define PCI_SUBDEVICE_ID_CISCO_CLEARLAKE 0x014d /* ClearLake pcie */ > > +/* Cruz MountTian2 SIOC */ > > +#define PCI_SUBDEVICE_ID_CISCO_MOUNTTIAN2 0x0157 > > +#define PCI_SUBDEVICE_ID_CISCO_CLAREMONT 0x015d /* Claremont MLOM */ > > + > > +/* Bodega */ > > +/* VIC 1457 PCIe mLOM */ > > +#define PCI_SUBDEVICE_ID_CISCO_BRADBURY 0x0218 > > +#define PCI_SUBDEVICE_ID_CISCO_BRENTWOOD 0x0217 /* VIC 1455 PCIe */ > > +/* VIC 1487 PCIe mLOM */ > > +#define PCI_SUBDEVICE_ID_CISCO_BURLINGAME 0x021a > > +#define PCI_SUBDEVICE_ID_CISCO_BAYSIDE 0x0219 /* VIC 1485 PCIe */ > > +/* VIC 1440 Mezz mLOM */ > > +#define PCI_SUBDEVICE_ID_CISCO_BAKERSFIELD 0x0215 > > +#define PCI_SUBDEVICE_ID_CISCO_BOONVILLE 0x0216 /* VIC 1480 Mezz */ > > +#define PCI_SUBDEVICE_ID_CISCO_BENICIA 0x024a /* VIC 1495 */ > > +#define PCI_SUBDEVICE_ID_CISCO_BEAUMONT 0x024b /* VIC 1497 */ > > +#define PCI_SUBDEVICE_ID_CISCO_BRISBANE 0x02af /* VIC 1467 */ > > +#define PCI_SUBDEVICE_ID_CISCO_BENTON 0x02b0 /* VIC 1477 */ > > +#define PCI_SUBDEVICE_ID_CISCO_TWIN_RIVER 0x02cf /* VIC 14425 */ > > +#define PCI_SUBDEVICE_ID_CISCO_TWIN_PEAK 0x02d0 /* VIC 14825 */ > > + > > +/* Beverly */ > > +#define PCI_SUBDEVICE_ID_CISCO_BERN 0x02de /* VIC 15420 */ > > +#define PCI_SUBDEVICE_ID_CISCO_STOCKHOLM 0x02dd /* VIC 15428 */ > > +#define PCI_SUBDEVICE_ID_CISCO_KRAKOW 0x02dc /* VIC 15411 */ > > +#define PCI_SUBDEVICE_ID_CISCO_LUCERNE 0x02db /* VIC 15231 */ > > +#define PCI_SUBDEVICE_ID_CISCO_TURKU 0x02e8 /* VIC 15238 */ > > +#define PCI_SUBDEVICE_ID_CISCO_TURKU_PLUS 0x02f3 /* VIC 15237 */ > > +#define PCI_SUBDEVICE_ID_CISCO_ZURICH 0x02df /* VIC 15230 */ > > +#define PCI_SUBDEVICE_ID_CISCO_RIGA 0x02e0 /* VIC 15427 */ > > +#define PCI_SUBDEVICE_ID_CISCO_GENEVA 0x02e1 /* VIC 15422 */ > > +#define PCI_SUBDEVICE_ID_CISCO_HELSINKI 0x02e4 /* VIC 15235 */ > > +#define PCI_SUBDEVICE_ID_CISCO_GOTHENBURG 0x02f2 /* VIC 15425 */ > > + > > +struct fnic_pcie_device { > > + u32 device; > > + u8 *desc; > > + u32 subsystem_device; > > + u8 *subsys_desc; > > +}; > > + > > /* > > * fnic private data per SCSI command. > > * These fields are locked by the hashed io_req_lock. > > @@ -134,6 +200,7 @@ static inline u64 fnic_flags_and_state(struct scsi_cmnd *cmd) > > #define fnic_clear_state_flags(fnicp, st_flags) \ > > __fnic_set_state_flags(fnicp, st_flags, 1) > > > > +extern unsigned int fnic_fdmi_support; > > extern unsigned int fnic_log_level; > > extern unsigned int io_completions; > > extern struct workqueue_struct *fnic_event_queue; @@ -366,6 +433,9 > > @@ struct fnic { > > > > /* interrupt resource cache line section */ > > ____cacheline_aligned struct vnic_intr intr[FNIC_MSIX_INTR_MAX]; > > + > > + char subsys_desc[14]; > > + int subsys_desc_len; > > }; > > > Please reconsider adding it here. > As the above entries are cacheline aligned there's a good chance you have introduced holes by placing it afterwards. I had not thought about that. Thanks for pointing this out. I'll make the change in the next version. > > static inline struct fnic *fnic_from_ctlr(struct fcoe_ctlr *fip) @@ > > -433,5 +503,7 @@ fnic_chk_state_flags_locked(struct fnic *fnic, unsigned long st_flags) > > void __fnic_set_state_flags(struct fnic *, unsigned long, unsigned long); > > void fnic_dump_fchost_stats(struct Scsi_Host *, struct fc_host_statistics *); > > void fnic_free_txq(struct list_head *head); > > +int fnic_get_desc_by_devid(struct pci_dev *pdev, char **desc, > > + char **subsys_desc); > > > > #endif /* _FNIC_H_ */ > > diff --git a/drivers/scsi/fnic/fnic_fdls.h > > b/drivers/scsi/fnic/fnic_fdls.h index 9eb25ed9c19f..88462363d754 > > 100644 > > --- a/drivers/scsi/fnic/fnic_fdls.h > > +++ b/drivers/scsi/fnic/fnic_fdls.h > > @@ -329,6 +329,7 @@ void fdls_send_tport_abts(struct fnic_iport_s *iport, > > struct fnic_tport_s *tport); > > void fdls_delete_tport(struct fnic_iport_s *iport, > > struct fnic_tport_s *tport); > > +void fdls_fdmi_timer_callback(struct timer_list *t); > > > > /* fnic_fcs.c */ > > void fnic_fdls_init(struct fnic *fnic, int usefip); @@ -366,4 +367,3 > > @@ struct fnic_tport_s *fnic_find_tport_by_wwpn(struct fnic_iport_s *iport, > > uint64_t wwpn); > > > > #endif /* _FNIC_FDLS_H_ */ > > - > > Tsk. Fixup the patch introducing fnic_fdls.h instead. fnic_fdls.h was introduced in patch 2. This is patch 6. The only concern with fixing up this patch with fnic_fdls.h is that it will break compilation of the intermediate patches i.e., from patch 3 to patch 5. I would like to avoid that. However, what I can do is to move these function declarations to patch 2, if that would be okay. > > diff --git a/drivers/scsi/fnic/fnic_main.c > > b/drivers/scsi/fnic/fnic_main.c index 577048e30c12..7d10d603f53b > > 100644 > > --- a/drivers/scsi/fnic/fnic_main.c > > +++ b/drivers/scsi/fnic/fnic_main.c > > @@ -62,6 +62,9 @@ unsigned int fnic_log_level; > > module_param(fnic_log_level, int, S_IRUGO|S_IWUSR); > > MODULE_PARM_DESC(fnic_log_level, "bit mask of fnic logging levels"); > > > > +unsigned int fnic_fdmi_support = 1; > > +module_param(fnic_fdmi_support, int, 0644); > > +MODULE_PARM_DESC(fnic_fdmi_support, "FDMI support"); > > > > unsigned int io_completions = FNIC_DFLT_IO_COMPLETIONS; > > module_param(io_completions, int, S_IRUGO|S_IWUSR); @@ -607,6 +610,8 > > @@ static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) > > int i; > > unsigned long flags; > > int hwq; > > + char *desc, *subsys_desc; > > + int len; > > > > /* > > * Allocate SCSI Host and set up association between host, @@ > > -640,6 +645,23 @@ static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) > > fnic->fnic_num = fnic_id; > > fnic_stats_debugfs_init(fnic); > > > > + /* Find model name from PCIe subsys ID */ > > + if (fnic_get_desc_by_devid(pdev, &desc, &subsys_desc) == 0) { > > + pr_info("Model: %s\n", subsys_desc); > > + > > + /* Update FDMI model */ > > + fnic->subsys_desc_len = strlen(subsys_desc); > > + len = ARRAY_SIZE(fnic->subsys_desc); > > + if (fnic->subsys_desc_len > len) > > + fnic->subsys_desc_len = len; > > + memcpy(fnic->subsys_desc, subsys_desc, fnic->subsys_desc_len); > > + pr_info("FDMI Model: %s\n", fnic->subsys_desc); > > + } else { > > + fnic->subsys_desc_len = 0; > > + pr_info("Model: %s subsys_id: 0x%04x\n", "Unknown", > > + pdev->subsystem_device); > > + } > > + > > err = pci_enable_device(pdev); > > if (err) { > > pr_err("Cannot enable PCI device, aborting.\n"); @@ -1014,6 > > +1036,9 @@ static void fnic_remove(struct pci_dev *pdev) > > fnic_fcoe_evlist_free(fnic); > > } > > > > + if ((fnic_fdmi_support == 1) && (fnic->iport.fabric.fdmi_pending > 0)) > > + del_timer_sync(&fnic->iport.fabric.fdmi_timer); > > + > > /* > > * Log off the fabric. This stops all remote ports, dns port, > > * logs off the fabric. This flushes all rport, disc, lport work @@ > > -1199,3 +1224,4 @@ static void __exit fnic_cleanup_module(void) > > > > module_init(fnic_init_module); > > module_exit(fnic_cleanup_module); > > + > > diff --git a/drivers/scsi/fnic/fnic_pci_subsys_devid.c > > b/drivers/scsi/fnic/fnic_pci_subsys_devid.c > > new file mode 100644 > > index 000000000000..1729c3a7ed05 > > --- /dev/null > > +++ b/drivers/scsi/fnic/fnic_pci_subsys_devid.c > > @@ -0,0 +1,133 @@ > > +// SPDX-License-Identifier: GPL-2.0-only > > +/* > > + * Copyright 2008 Cisco Systems, Inc. All rights reserved. > > + * Copyright 2007 Nuova Systems, Inc. All rights reserved. > > + */ > > + > > +#include <linux/module.h> > > +#include <linux/mempool.h> > > +#include <linux/string.h> > > +#include <linux/slab.h> > > +#include <linux/version.h> > > +#include <linux/errno.h> > > +#include <linux/init.h> > > +#include <linux/pci.h> > > +#include <linux/interrupt.h> > > +#include <linux/irq.h> > > +#include <linux/spinlock.h> > > +#include <linux/workqueue.h> > > +#include <linux/kthread.h> > > +#include <linux/if_ether.h> > > +#include "fnic.h" > > + > > +static struct fnic_pcie_device fnic_pcie_device_table[] = { > > + {PCI_DEVICE_ID_CISCO_SERENO, "Sereno", PCI_SUBDEVICE_ID_CISCO_VASONA, > > + "VIC 1280"}, > > + {PCI_DEVICE_ID_CISCO_SERENO, "Sereno", PCI_SUBDEVICE_ID_CISCO_COTATI, > > + "VIC 1240"}, > > + {PCI_DEVICE_ID_CISCO_SERENO, "Sereno", > > + PCI_SUBDEVICE_ID_CISCO_LEXINGTON, "VIC 1225"}, > > + {PCI_DEVICE_ID_CISCO_SERENO, "Sereno", PCI_SUBDEVICE_ID_CISCO_ICEHOUSE, > > + "VIC 1285"}, > > + {PCI_DEVICE_ID_CISCO_SERENO, "Sereno", > > + PCI_SUBDEVICE_ID_CISCO_KIRKWOODLAKE, "VIC 1225T"}, > > + {PCI_DEVICE_ID_CISCO_SERENO, "Sereno", > > + PCI_SUBDEVICE_ID_CISCO_SUSANVILLE, "VIC 1227"}, > > + {PCI_DEVICE_ID_CISCO_SERENO, "Sereno", PCI_SUBDEVICE_ID_CISCO_TORRANCE, > > + "VIC 1227T"}, > > + > > + {PCI_DEVICE_ID_CISCO_CRUZ, "Cruz", PCI_SUBDEVICE_ID_CISCO_CALISTOGA, > > + "VIC 1340"}, > > + {PCI_DEVICE_ID_CISCO_CRUZ, "Cruz", PCI_SUBDEVICE_ID_CISCO_MOUNTAINVIEW, > > + "VIC 1380"}, > > + {PCI_DEVICE_ID_CISCO_CRUZ, "Cruz", PCI_SUBDEVICE_ID_CISCO_MOUNTTIAN, > > + "C3260-SIOC"}, > > + {PCI_DEVICE_ID_CISCO_CRUZ, "Cruz", PCI_SUBDEVICE_ID_CISCO_CLEARLAKE, > > + "VIC 1385"}, > > + {PCI_DEVICE_ID_CISCO_CRUZ, "Cruz", PCI_SUBDEVICE_ID_CISCO_MOUNTTIAN2, > > + "C3260-SIOC"}, > > + {PCI_DEVICE_ID_CISCO_CRUZ, "Cruz", PCI_SUBDEVICE_ID_CISCO_CLAREMONT, > > + "VIC 1387"}, > > + > > + {PCI_DEVICE_ID_CISCO_BODEGA, "Bodega", PCI_SUBDEVICE_ID_CISCO_BRADBURY, > > + "VIC 1457"}, > > + {PCI_DEVICE_ID_CISCO_BODEGA, "Bodega", > > + PCI_SUBDEVICE_ID_CISCO_BRENTWOOD, "VIC 1455"}, > > + {PCI_DEVICE_ID_CISCO_BODEGA, "Bodega", > > + PCI_SUBDEVICE_ID_CISCO_BURLINGAME, "VIC 1487"}, > > + {PCI_DEVICE_ID_CISCO_BODEGA, "Bodega", PCI_SUBDEVICE_ID_CISCO_BAYSIDE, > > + "VIC 1485"}, > > + {PCI_DEVICE_ID_CISCO_BODEGA, "Bodega", > > + PCI_SUBDEVICE_ID_CISCO_BAKERSFIELD, "VIC 1440"}, > > + {PCI_DEVICE_ID_CISCO_BODEGA, "Bodega", > > + PCI_SUBDEVICE_ID_CISCO_BOONVILLE, "VIC 1480"}, > > + {PCI_DEVICE_ID_CISCO_BODEGA, "Bodega", PCI_SUBDEVICE_ID_CISCO_BENICIA, > > + "VIC 1495"}, > > + {PCI_DEVICE_ID_CISCO_BODEGA, "Bodega", PCI_SUBDEVICE_ID_CISCO_BEAUMONT, > > + "VIC 1497"}, > > + {PCI_DEVICE_ID_CISCO_BODEGA, "Bodega", PCI_SUBDEVICE_ID_CISCO_BRISBANE, > > + "VIC 1467"}, > > + {PCI_DEVICE_ID_CISCO_BODEGA, "Bodega", PCI_SUBDEVICE_ID_CISCO_BENTON, > > + "VIC 1477"}, > > + {PCI_DEVICE_ID_CISCO_BODEGA, "Bodega", > > + PCI_SUBDEVICE_ID_CISCO_TWIN_RIVER, "VIC 14425"}, > > + {PCI_DEVICE_ID_CISCO_BODEGA, "Bodega", > > + PCI_SUBDEVICE_ID_CISCO_TWIN_PEAK, "VIC 14825"}, > > + > > + {PCI_DEVICE_ID_CISCO_BEVERLY, "Beverly", PCI_SUBDEVICE_ID_CISCO_BERN, > > + "VIC 15420"}, > > + {PCI_DEVICE_ID_CISCO_BEVERLY, "Beverly", > > + PCI_SUBDEVICE_ID_CISCO_STOCKHOLM, "VIC 15428"}, > > + {PCI_DEVICE_ID_CISCO_BEVERLY, "Beverly", PCI_SUBDEVICE_ID_CISCO_KRAKOW, > > + "VIC 15411"}, > > + {PCI_DEVICE_ID_CISCO_BEVERLY, "Beverly", > > + PCI_SUBDEVICE_ID_CISCO_LUCERNE, "VIC 15231"}, > > + {PCI_DEVICE_ID_CISCO_BEVERLY, "Beverly", PCI_SUBDEVICE_ID_CISCO_TURKU, > > + "VIC 15238"}, > > + {PCI_DEVICE_ID_CISCO_BEVERLY, "Beverly", PCI_SUBDEVICE_ID_CISCO_GENEVA, > > + "VIC 15422"}, > > + {PCI_DEVICE_ID_CISCO_BEVERLY, "Beverly", > > + PCI_SUBDEVICE_ID_CISCO_HELSINKI, "VIC 15235"}, > > + {PCI_DEVICE_ID_CISCO_BEVERLY, "Beverly", > > + PCI_SUBDEVICE_ID_CISCO_GOTHENBURG, "VIC 15425"}, > > + {PCI_DEVICE_ID_CISCO_BEVERLY, "Beverly", > > + PCI_SUBDEVICE_ID_CISCO_TURKU_PLUS, "VIC 15237"}, > > + {PCI_DEVICE_ID_CISCO_BEVERLY, "Beverly", PCI_SUBDEVICE_ID_CISCO_ZURICH, > > + "VIC 15230"}, > > + {PCI_DEVICE_ID_CISCO_BEVERLY, "Beverly", PCI_SUBDEVICE_ID_CISCO_RIGA, > > + "VIC 15427"}, > > + > > + {0,} > > +}; > > + > > +int fnic_get_desc_by_devid(struct pci_dev *pdev, char **desc, > > + char **subsys_desc) > > +{ > > + unsigned short device = PCI_DEVICE_ID_CISCO_VIC_FC; > > + int max = ARRAY_SIZE(fnic_pcie_device_table); > > + struct fnic_pcie_device *t = fnic_pcie_device_table; > > + int index = 0; > > + > > + if (memcmp((char *) &pdev->device, (char *) &device, sizeof(short)) != > > + 0) > > + return 1; > > + > > What on earth ... you are not seriously comparing unsigned shorts via memcmp? What happened to the good old '=='? > Bah. > Thanks for pointing this out, Hannes. I'll fix this in the next version. Regards, Karan