Commit a257bf90 authored by James Smart's avatar James Smart Committed by James Bottomley
Browse files

[SCSI] lpfc 8.3.1: misc fixes/changes



8.3.1 Fixes/Changes :

- Fix incorrect byte-swapping on word 4 of IOCB (data length) which
  caused LUNs to not be discovered on big-endian (e.g. PPC)

- Remove a bad cast of MBslimaddr which loses the __iomem (sparse)

- Make lpfc_debugfs_mask_disc_trc static (sparse)

- Correct misspelled word BlockGuard in lpfc_logmsg.h comment

- Replaced repeated code segment for canceling IOCBs from a list with
  a function call, lpfc_sli_cancel_iocbs().

- Increased HBQ buffers to support 40KB SSC sequences.

- Added sysfs interface to update speed and topology parameter without
  link bounce.

- Fixed bug with sysfs fc_host WWNs not being updated after changing
  the WWNs.

- Check if the active mailbox is NULL in the beginning of the mailbox
  timeout handler - fixes panic in the mailbox timeout handler while
  running IO stress test

- Fixed system panic in lpfc_pci_remove_one() due to ndlp indirect
  reference to phba through vport

- Removed de-reference of scsi device after call to scsi_done() to fix
  panic in scsi completion path while accessing scsi device after
  scsi_done is called.

- Fixed "Nodelist not empty" message when unloading the driver after
  target reboot test

- Added LP2105 HBA model description

- Added code to print all 16 words of unrecognized ASYNC events

- Fixed memory leak in vport create + delete loop

- Added support for handling dual error bit from HBA

- Fixed a driver NULL pointer dereference in lpfc_sli_process_sol_iocb

- Fixed a discovery bug with FC switch reboot in lpfc_setup_disc_node

- Take NULL termintator into account when calculating available buffer space

Signed-off-by: default avatarJames Smart <james.smart@emulex.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@HansenPartnership.com>
parent 3621a710
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -443,6 +443,7 @@ struct lpfc_hba {
	uint32_t hba_flag;	/* hba generic flags */
#define HBA_ERATT_HANDLED	0x1 /* This flag is set when eratt handled */

#define DEFER_ERATT		0x4 /* Deferred error attention in progress */
	struct lpfc_dmabuf slim2p;

	MAILBOX_t *mbox;
@@ -723,4 +724,3 @@ lpfc_sli_read_hs(struct lpfc_hba *phba)

	return;
}
+55 −12
Original line number Diff line number Diff line
@@ -2216,18 +2216,41 @@ LPFC_VPORT_ATTR_R(scan_down, 1, 0, 1,
 * non-zero return value from lpfc_issue_lip()
 * -EINVAL val out of range
 **/
static int
lpfc_topology_set(struct lpfc_hba *phba, int val)
static ssize_t
lpfc_topology_store(struct device *dev, struct device_attribute *attr,
			const char *buf, size_t count)
{
	struct Scsi_Host  *shost = class_to_shost(dev);
	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
	struct lpfc_hba   *phba = vport->phba;
	int val = 0;
	int nolip = 0;
	const char *val_buf = buf;
	int err;
	uint32_t prev_val;

	if (!strncmp(buf, "nolip ", strlen("nolip "))) {
		nolip = 1;
		val_buf = &buf[strlen("nolip ")];
	}

	if (!isdigit(val_buf[0]))
		return -EINVAL;
	if (sscanf(val_buf, "%i", &val) != 1)
		return -EINVAL;

	if (val >= 0 && val <= 6) {
		prev_val = phba->cfg_topology;
		phba->cfg_topology = val;
		if (nolip)
			return strlen(buf);

		err = lpfc_issue_lip(lpfc_shost_from_vport(phba->pport));
		if (err)
		if (err) {
			phba->cfg_topology = prev_val;
		return err;
			return -EINVAL;
		} else
			return strlen(buf);
	}
	lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
		"%d:0467 lpfc_topology attribute cannot be set to %d, "
@@ -2240,7 +2263,6 @@ module_param(lpfc_topology, int, 0);
MODULE_PARM_DESC(lpfc_topology, "Select Fibre Channel topology");
lpfc_param_show(topology)
lpfc_param_init(topology, 0, 0, 6)
lpfc_param_store(topology)
static DEVICE_ATTR(lpfc_topology, S_IRUGO | S_IWUSR,
		lpfc_topology_show, lpfc_topology_store);

@@ -2281,7 +2303,7 @@ lpfc_stat_data_ctrl_store(struct device *dev, struct device_attribute *attr,
	unsigned long base, step, bucket_type;

	if (!strncmp(buf, "setbucket", strlen("setbucket"))) {
		if (strlen(buf) > LPFC_MAX_DATA_CTRL_LEN)
		if (strlen(buf) > (LPFC_MAX_DATA_CTRL_LEN - 1))
			return -EINVAL;

		strcpy(bucket_data, buf);
@@ -2598,12 +2620,29 @@ static struct bin_attribute sysfs_drvr_stat_data_attr = {
 * non-zero return value from lpfc_issue_lip()
 * -EINVAL val out of range
 **/
static int
lpfc_link_speed_set(struct lpfc_hba *phba, int val)
static ssize_t
lpfc_link_speed_store(struct device *dev, struct device_attribute *attr,
		const char *buf, size_t count)
{
	struct Scsi_Host  *shost = class_to_shost(dev);
	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
	struct lpfc_hba   *phba = vport->phba;
	int val = 0;
	int nolip = 0;
	const char *val_buf = buf;
	int err;
	uint32_t prev_val;

	if (!strncmp(buf, "nolip ", strlen("nolip "))) {
		nolip = 1;
		val_buf = &buf[strlen("nolip ")];
	}

	if (!isdigit(val_buf[0]))
		return -EINVAL;
	if (sscanf(val_buf, "%i", &val) != 1)
		return -EINVAL;

	if (((val == LINK_SPEED_1G) && !(phba->lmt & LMT_1Gb)) ||
		((val == LINK_SPEED_2G) && !(phba->lmt & LMT_2Gb)) ||
		((val == LINK_SPEED_4G) && !(phba->lmt & LMT_4Gb)) ||
@@ -2611,14 +2650,19 @@ lpfc_link_speed_set(struct lpfc_hba *phba, int val)
		((val == LINK_SPEED_10G) && !(phba->lmt & LMT_10Gb)))
		return -EINVAL;

	if ((val >= 0 && val <= LPFC_MAX_LINK_SPEED)
	if ((val >= 0 && val <= 8)
		&& (LPFC_LINK_SPEED_BITMAP & (1 << val))) {
		prev_val = phba->cfg_link_speed;
		phba->cfg_link_speed = val;
		if (nolip)
			return strlen(buf);

		err = lpfc_issue_lip(lpfc_shost_from_vport(phba->pport));
		if (err)
		if (err) {
			phba->cfg_link_speed = prev_val;
		return err;
			return -EINVAL;
		} else
			return strlen(buf);
	}

	lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
@@ -2665,7 +2709,6 @@ lpfc_link_speed_init(struct lpfc_hba *phba, int val)
	return -EINVAL;
}

lpfc_param_store(link_speed)
static DEVICE_ATTR(lpfc_link_speed, S_IRUGO | S_IWUSR,
		lpfc_link_speed_show, lpfc_link_speed_store);

+2 −0
Original line number Diff line number Diff line
@@ -184,6 +184,8 @@ void lpfc_sli_poll_fcp_ring(struct lpfc_hba *);
struct lpfc_iocbq * lpfc_sli_get_iocbq(struct lpfc_hba *);
void lpfc_sli_release_iocbq(struct lpfc_hba *, struct lpfc_iocbq *);
uint16_t lpfc_sli_next_iotag(struct lpfc_hba *, struct lpfc_iocbq *);
void lpfc_sli_cancel_iocbs(struct lpfc_hba *, struct list_head *, uint32_t,
			   uint32_t);

void lpfc_reset_barrier(struct lpfc_hba * phba);
int lpfc_sli_brdready(struct lpfc_hba *, uint32_t);
+2 −3
Original line number Diff line number Diff line
@@ -95,7 +95,7 @@ module_param(lpfc_debugfs_max_slow_ring_trc, int, 0);
MODULE_PARM_DESC(lpfc_debugfs_max_slow_ring_trc,
	"Set debugfs slow ring trace depth");

int lpfc_debugfs_mask_disc_trc;
static int lpfc_debugfs_mask_disc_trc;
module_param(lpfc_debugfs_mask_disc_trc, int, 0);
MODULE_PARM_DESC(lpfc_debugfs_mask_disc_trc,
	"Set debugfs discovery trace mask");
@@ -399,8 +399,7 @@ lpfc_debugfs_dumpHBASlim_data(struct lpfc_hba *phba, char *buf, int size)

	len +=  snprintf(buf+len, size-len, "HBA SLIM\n");
	lpfc_memcpy_from_slim(buffer,
		((uint8_t *)phba->MBslimaddr) + lpfc_debugfs_last_hba_slim_off,
		1024);
		phba->MBslimaddr + lpfc_debugfs_last_hba_slim_off, 1024);

	ptr = (uint32_t *)&buffer[0];
	off = lpfc_debugfs_last_hba_slim_off;
+1 −0
Original line number Diff line number Diff line
@@ -99,6 +99,7 @@ struct lpfc_nodelist {
#define NLP_USG_FREE_ACK_BIT	0x8	/* Indicate ndlp memory free invoked */

	struct timer_list   nlp_delayfunc;	/* Used for delayed ELS cmds */
	struct lpfc_hba *phba;
	struct fc_rport *rport;			/* Corresponding FC transport
						   port structure */
	struct lpfc_vport *vport;
Loading