Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a7a167bf authored by Andrew Vasquez's avatar Andrew Vasquez Committed by James Bottomley
Browse files

[SCSI] qla2xxx: Rework firmware-trace facilities.



- Defer firmware dump-data raw-to-textual conversion to
  user-space.
- Add module parameter (ql2xallocfwdump) to allow for per-HBA
  allocations of firmware dump memory.
- Dump request and response queue data as per firmware group
  request.
- Add extended firmware trace support for ISP24XX/ISP54XX chips.

Signed-off-by: default avatarAndrew Vasquez <andrew.vasquez@qlogic.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent 9ea72909
Loading
Loading
Loading
Loading
+17 −36
Original line number Diff line number Diff line
@@ -16,15 +16,16 @@ qla2x00_sysfs_read_fw_dump(struct kobject *kobj, char *buf, loff_t off,
{
	struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
	    struct device, kobj)));
	char *rbuf = (char *)ha->fw_dump;

	if (ha->fw_dump_reading == 0)
		return 0;
	if (off > ha->fw_dump_buffer_len)
	if (off > ha->fw_dump_len)
                return 0;
	if (off + count > ha->fw_dump_buffer_len)
		count = ha->fw_dump_buffer_len - off;
	if (off + count > ha->fw_dump_len)
		count = ha->fw_dump_len - off;

	memcpy(buf, &ha->fw_dump_buffer[off], count);
	memcpy(buf, &rbuf[off], count);

	return (count);
}
@@ -36,7 +37,6 @@ qla2x00_sysfs_write_fw_dump(struct kobject *kobj, char *buf, loff_t off,
	struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj,
	    struct device, kobj)));
	int reading;
	uint32_t dump_size;

	if (off != 0)
		return (0);
@@ -44,46 +44,27 @@ qla2x00_sysfs_write_fw_dump(struct kobject *kobj, char *buf, loff_t off,
	reading = simple_strtol(buf, NULL, 10);
	switch (reading) {
	case 0:
		if (ha->fw_dump_reading == 1) {
		if (!ha->fw_dump_reading)
			break;

		qla_printk(KERN_INFO, ha,
		    "Firmware dump cleared on (%ld).\n", ha->host_no);

			vfree(ha->fw_dump_buffer);
			ha->fw_dump_buffer = NULL;
		ha->fw_dump_reading = 0;
		ha->fw_dumped = 0;
		}
		break;
	case 1:
		if (ha->fw_dumped && !ha->fw_dump_reading) {
			ha->fw_dump_reading = 1;

			if (IS_QLA24XX(ha) || IS_QLA54XX(ha))
				dump_size = FW_DUMP_SIZE_24XX;
			else {
				dump_size = FW_DUMP_SIZE_1M;
				if (ha->fw_memory_size < 0x20000)
					dump_size = FW_DUMP_SIZE_128K;
				else if (ha->fw_memory_size < 0x80000)
					dump_size = FW_DUMP_SIZE_512K;
			}
			ha->fw_dump_buffer = (char *)vmalloc(dump_size);
			if (ha->fw_dump_buffer == NULL) {
				qla_printk(KERN_WARNING, ha,
				    "Unable to allocate memory for firmware "
				    "dump buffer (%d).\n", dump_size);

				ha->fw_dump_reading = 0;
				return (count);
			}
			qla_printk(KERN_INFO, ha,
			    "Firmware dump ready for read on (%ld).\n",
			    "Raw firmware dump ready for read on (%ld).\n",
			    ha->host_no);
			memset(ha->fw_dump_buffer, 0, dump_size);
			ha->isp_ops.ascii_fw_dump(ha);
			ha->fw_dump_buffer_len = strlen(ha->fw_dump_buffer);
		}
		break;
	case 2:
		qla2x00_alloc_fw_dump(ha);
		break;
	}
	return (count);
}
+183 −742

File changed.

Preview size limit exceeded, changes collapsed.

+36 −5
Original line number Diff line number Diff line
@@ -176,9 +176,6 @@
/*
 * Firmware Dump structure definition
 */
#define FW_DUMP_SIZE_128K	0xBC000
#define FW_DUMP_SIZE_512K	0x2FC000
#define FW_DUMP_SIZE_1M		0x5FC000

struct qla2300_fw_dump {
	uint16_t hccr;
@@ -224,8 +221,6 @@ struct qla2100_fw_dump {
	uint16_t risc_ram[0xf000];
};

#define FW_DUMP_SIZE_24XX	0x2B0000

struct qla24xx_fw_dump {
	uint32_t host_status;
	uint32_t host_reg[32];
@@ -257,3 +252,39 @@ struct qla24xx_fw_dump {
	uint32_t code_ram[0x2000];
	uint32_t ext_mem[1];
};

#define EFT_NUM_BUFFERS		4
#define EFT_BYTES_PER_BUFFER	0x4000
#define EFT_SIZE		((EFT_BYTES_PER_BUFFER) * (EFT_NUM_BUFFERS))

struct qla2xxx_fw_dump {
	uint8_t signature[4];
	uint32_t version;

	uint32_t fw_major_version;
	uint32_t fw_minor_version;
	uint32_t fw_subminor_version;
	uint32_t fw_attributes;

	uint32_t vendor;
	uint32_t device;
	uint32_t subsystem_vendor;
	uint32_t subsystem_device;

	uint32_t fixed_size;
	uint32_t mem_size;
	uint32_t req_q_size;
	uint32_t rsp_q_size;

	uint32_t eft_size;
	uint32_t eft_addr_l;
	uint32_t eft_addr_h;

	uint32_t header_size;

	union {
		struct qla2100_fw_dump isp21;
		struct qla2300_fw_dump isp23;
		struct qla24xx_fw_dump isp24;
	} isp;
};
+8 −4
Original line number Diff line number Diff line
@@ -608,6 +608,7 @@ typedef struct {
#define MBC_SERDES_PARAMS		0x10	/* Serdes Tx Parameters. */
#define MBC_GET_IOCB_STATUS		0x12	/* Get IOCB status command. */
#define MBC_GET_TIMEOUT_PARAMS		0x22	/* Get FW timeouts. */
#define MBC_TRACE_CONTROL		0x27	/* Trace control command. */
#define MBC_GEN_SYSTEM_ERROR		0x2a	/* Generate System Error. */
#define MBC_SET_TIMEOUT_PARAMS		0x32	/* Set FW timeouts. */
#define MBC_MID_INITIALIZE_FIRMWARE	0x48	/* MID Initialize firmware. */
@@ -618,6 +619,9 @@ typedef struct {
#define MBC_GET_LINK_PRIV_STATS		0x6d	/* Get link & private data. */
#define MBC_SET_VENDOR_ID		0x76	/* Set Vendor ID. */

#define TC_ENABLE			4
#define TC_DISABLE			5

/* Firmware return data sizes */
#define FCAL_MAP_SIZE	128

@@ -1997,7 +2001,6 @@ struct isp_operations {
		uint32_t);

	void (*fw_dump) (struct scsi_qla_host *, int);
	void (*ascii_fw_dump) (struct scsi_qla_host *);

	int (*beacon_on) (struct scsi_qla_host *);
	int (*beacon_off) (struct scsi_qla_host *);
@@ -2303,11 +2306,12 @@ typedef struct scsi_qla_host {
	uint16_t	fw_seriallink_options24[4];

	/* Firmware dump information. */
	void		*fw_dump;
	struct qla2xxx_fw_dump *fw_dump;
	uint32_t	fw_dump_len;
	int		fw_dumped;
	int		fw_dump_reading;
	char		*fw_dump_buffer;
	int		fw_dump_buffer_len;
	dma_addr_t	eft_dma;
	void		*eft;

	uint8_t		host_str[16];
	uint32_t	pci_attr;
+6 −3
Original line number Diff line number Diff line
@@ -51,6 +51,8 @@ extern int qla2x00_abort_isp(scsi_qla_host_t *);
extern void qla2x00_update_fcport(scsi_qla_host_t *, fc_port_t *);
extern void qla2x00_reg_remote_port(scsi_qla_host_t *, fc_port_t *);

extern void qla2x00_alloc_fw_dump(scsi_qla_host_t *);

/*
 * Global Data in qla_os.c source file.
 */
@@ -61,6 +63,7 @@ extern int qlport_down_retry;
extern int ql2xplogiabsentdevice;
extern int ql2xloginretrycount;
extern int ql2xfdmienable;
extern int ql2xallocfwdump;

extern void qla2x00_sp_compl(scsi_qla_host_t *, srb_t *);

@@ -204,6 +207,9 @@ qla2x00_set_serdes_params(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t);
extern int
qla2x00_stop_firmware(scsi_qla_host_t *);

extern int
qla2x00_trace_control(scsi_qla_host_t *, uint16_t, dma_addr_t, uint16_t);

/*
 * Global Function Prototypes in qla_isr.c source file.
 */
@@ -254,9 +260,6 @@ extern int qla24xx_write_optrom_data(struct scsi_qla_host *, uint8_t *,
extern void qla2100_fw_dump(scsi_qla_host_t *, int);
extern void qla2300_fw_dump(scsi_qla_host_t *, int);
extern void qla24xx_fw_dump(scsi_qla_host_t *, int);
extern void qla2100_ascii_fw_dump(scsi_qla_host_t *);
extern void qla2300_ascii_fw_dump(scsi_qla_host_t *);
extern void qla24xx_ascii_fw_dump(scsi_qla_host_t *);
extern void qla2x00_dump_regs(scsi_qla_host_t *);
extern void qla2x00_dump_buffer(uint8_t *, uint32_t);
extern void qla2x00_print_scsi_cmd(struct scsi_cmnd *);
Loading