Date: Mon, 25 Sep 2006 15:03:34 -0500 From: Mike Christie <mchristi@redhat.com> Subject: Re: [PATCH RHEL5] add qla4xxx ioctl module hooks Attached is a updated patch from qlogic. It has been compile tested by me and tested by qlogic. diff -aurp linux-2.6.18.noarch/drivers/scsi/qla4xxx/ql4_def.h linux-2.6.18.noarch.ioctl2/drivers/scsi/qla4xxx/ql4_def.h --- linux-2.6.18.noarch/drivers/scsi/qla4xxx/ql4_def.h 2006-09-25 14:06:59.000000000 -0500 +++ linux-2.6.18.noarch.ioctl2/drivers/scsi/qla4xxx/ql4_def.h 2006-09-25 14:13:26.000000000 -0500 @@ -155,6 +155,7 @@ struct srb { struct ddb_entry *ddb; uint16_t flags; /* (1) Status flags. */ +#define SRB_SCSI_PASSTHRU BIT_2 /* for scsi passthru cmds */ #define SRB_DMA_VALID BIT_3 /* DMA Buffer mapped. */ #define SRB_GOT_SENSE BIT_4 /* sense data recieved. */ uint8_t state; /* (1) Status flags. */ @@ -265,6 +266,9 @@ struct aen { * Linux Host Adapter structure */ struct scsi_qla_host { + struct klist_node node; + uint16_t instance; + uint16_t rsvd0; /* Linux adapter configuration data */ struct Scsi_Host *host; /* pointer to host data */ uint32_t tot_ddbs; @@ -429,6 +433,12 @@ struct scsi_qla_host { struct mutex mbox_sem; wait_queue_head_t mailbox_wait_queue; + /* exported functions */ + int (*ql4cmd)(struct scsi_qla_host *ha, struct srb * srb); + int (*ql4mbx)(struct scsi_qla_host *ha, uint8_t inCount, + uint8_t outCount, uint32_t *mbx_cmd, + uint32_t *mbx_sts); + /* temporary mailbox status registers */ volatile uint8_t mbox_status_count; volatile uint32_t mbox_status[MBOX_REG_COUNT]; @@ -438,7 +448,6 @@ struct scsi_qla_host { /* Map ddb_list entry by FW ddb index */ struct ddb_entry *fw_ddb_index_map[MAX_DDB_ENTRIES]; - }; static inline int is_qla4010(struct scsi_qla_host *ha) diff -aurp linux-2.6.18.noarch/drivers/scsi/qla4xxx/ql4_glbl.h linux-2.6.18.noarch.ioctl2/drivers/scsi/qla4xxx/ql4_glbl.h --- linux-2.6.18.noarch/drivers/scsi/qla4xxx/ql4_glbl.h 2006-09-25 14:06:59.000000000 -0500 +++ linux-2.6.18.noarch.ioctl2/drivers/scsi/qla4xxx/ql4_glbl.h 2006-09-25 14:13:26.000000000 -0500 @@ -73,6 +73,9 @@ int qla4xxx_process_ddb_changed(struct s uint32_t fw_ddb_index, uint32_t state); void qla4xxx_free_pdu(struct scsi_qla_host * ha, struct pdu_entry * pdu); +int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount, + uint8_t outCount, uint32_t *mbx_cmd, uint32_t *mbx_sts); + extern int extended_error_logging; extern int ql4xdiscoverywait; diff -aurp linux-2.6.18.noarch/drivers/scsi/qla4xxx/ql4_iocb.c linux-2.6.18.noarch.ioctl2/drivers/scsi/qla4xxx/ql4_iocb.c --- linux-2.6.18.noarch/drivers/scsi/qla4xxx/ql4_iocb.c 2006-09-25 14:06:59.000000000 -0500 +++ linux-2.6.18.noarch.ioctl2/drivers/scsi/qla4xxx/ql4_iocb.c 2006-09-25 14:13:26.000000000 -0500 @@ -379,23 +379,27 @@ int qla4xxx_send_command_to_isp(struct s } /* Calculate the number of request entries needed. */ - if (cmd->use_sg) { - sg = (struct scatterlist *)cmd->request_buffer; - tot_dsds = pci_map_sg(ha->pdev, sg, cmd->use_sg, + if (srb->flags & SRB_SCSI_PASSTHRU) { + tot_dsds = 1; + } else { + if (cmd->use_sg) { + sg = (struct scatterlist *)cmd->request_buffer; + tot_dsds = pci_map_sg(ha->pdev, sg, cmd->use_sg, cmd->sc_data_direction); - if (tot_dsds == 0) - goto queuing_error; - } else if (cmd->request_bufflen) { - dma_addr_t req_dma; + if (tot_dsds == 0) + goto queuing_error; + } else if (cmd->request_bufflen) { + dma_addr_t req_dma; - req_dma = pci_map_single(ha->pdev, cmd->request_buffer, + req_dma = pci_map_single(ha->pdev, cmd->request_buffer, cmd->request_bufflen, cmd->sc_data_direction); - if (dma_mapping_error(req_dma)) - goto queuing_error; + if (dma_mapping_error(req_dma)) + goto queuing_error; - srb->dma_handle = req_dma; - tot_dsds = 1; + srb->dma_handle = req_dma; + tot_dsds = 1; + } } req_cnt = qla4xxx_calc_request_entries(tot_dsds); @@ -501,6 +505,9 @@ int qla4xxx_send_command_to_isp(struct s return QLA_SUCCESS; queuing_error: + if (srb->flags & SRB_SCSI_PASSTHRU) + return QLA_ERROR; + if (cmd->use_sg && tot_dsds) { sg = (struct scatterlist *) cmd->request_buffer; pci_unmap_sg(ha->pdev, sg, cmd->use_sg, diff -aurp linux-2.6.18.noarch/drivers/scsi/qla4xxx/ql4_os.c linux-2.6.18.noarch.ioctl2/drivers/scsi/qla4xxx/ql4_os.c --- linux-2.6.18.noarch/drivers/scsi/qla4xxx/ql4_os.c 2006-09-25 14:06:59.000000000 -0500 +++ linux-2.6.18.noarch.ioctl2/drivers/scsi/qla4xxx/ql4_os.c 2006-09-25 14:13:26.000000000 -0500 @@ -9,6 +9,7 @@ #include <scsi/scsi_tcq.h> #include <scsi/scsicam.h> +#include <linux/klist.h> #include "ql4_def.h" /* @@ -16,6 +17,16 @@ */ char qla4xxx_version_str[40]; +/* + * List of host adapters + */ +struct klist qla4xxx_hostlist; + +struct klist *qla4xxx_hostlist_ptr = &qla4xxx_hostlist; +EXPORT_SYMBOL_GPL(qla4xxx_hostlist_ptr); + +atomic_t qla4xxx_hba_count; + /* * SRB allocation cache */ @@ -387,10 +398,10 @@ void qla4xxx_srb_compl(struct scsi_qla_h { struct scsi_cmnd *cmd = srb->cmd; - qla4xxx_srb_free_dma(ha, srb); - - mempool_free(srb, ha->srb_mempool); - + if (!(srb->flags & SRB_SCSI_PASSTHRU)) { + qla4xxx_srb_free_dma(ha, srb); + mempool_free(srb, ha->srb_mempool); + } cmd->scsi_done(cmd); } @@ -1243,6 +1254,9 @@ static int __devinit qla4xxx_probe_adapt ha->host = host; ha->host_no = host->host_no; + ha->ql4mbx = qla4xxx_mailbox_command; + ha->ql4cmd = qla4xxx_send_command_to_isp; + /* Configure PCI I/O space. */ ret = qla4xxx_iospace_config(ha); if (ret) @@ -1349,6 +1363,13 @@ static int __devinit qla4xxx_probe_adapt ha->host_no, ha->firmware_version[0], ha->firmware_version[1], ha->patch_number, ha->build_number); + /* Insert new entry into the list of adapters. */ + klist_add_tail(&ha->node, &qla4xxx_hostlist); + ha->instance = atomic_inc_return(&qla4xxx_hba_count) - 1; + + DEBUG2(printk("qla4xxx: listhead=%p, done adding ha=%p i=%d\n", + &qla4xxx_hostlist, &ha->node, ha->instance);) + return 0; remove_host: @@ -1375,6 +1396,9 @@ static void __devexit qla4xxx_remove_ada ha = pci_get_drvdata(pdev); + klist_remove(&ha->node); + atomic_dec(&qla4xxx_hba_count); + /* remove devs from iscsi_sessions to scsi_devices */ qla4xxx_free_ddb_list(ha); @@ -1704,6 +1728,8 @@ static int __init qla4xxx_module_init(vo { int ret; + atomic_set(&qla4xxx_hba_count, 0); + klist_init(&qla4xxx_hostlist, NULL, NULL); /* Allocate cache for SRBs. */ srb_cachep = kmem_cache_create("qla4xxx_srbs", sizeof(struct srb), 0, SLAB_HWCACHE_ALIGN, NULL, NULL);