stex:use config struct for parameters of different controllers
PATCH 3/5 stex:use config struct for parameters of different controllers
Use config struct (st_card_info) for parameters of different controllers
Signed-off-by Ed Lin <[email protected]>
---
drivers/scsi/stex.c | 201 ++++++++++++++++++++++++++++++++------------------- 1 files changed, 125 insertions(+), 76 deletions(-)
drivers/scsi/stex.c +125 -76
@@ -95,19 +95,8 @@ enum {TASK_ATTRIBUTE_ORDERED =0x2 ,TASK_ATTRIBUTE_ACA =0x4 , -/* request count, etc. */ -MU_MAX_REQUEST =32 , - -/* one message wasted, use MU_MAX_REQUEST+1 -to handle MU_MAX_REQUEST messages */ -MU_REQ_COUNT = (MU_MAX_REQUEST +1 ), -MU_STATUS_COUNT = (MU_MAX_REQUEST +1 ), -STEX_CDB_LENGTH =16 , -REQ_VARIABLE_LEN =1024 ,STATUS_VAR_LEN =128 , -ST_CAN_QUEUE =MU_MAX_REQUEST , -ST_CMD_PER_LUN =MU_MAX_REQUEST , ST_MAX_SG = 32,/* sg flags */
@@ -120,9 +109,8 @@ enum { st_shasta =0 , st_vsc =1 , - st_vsc1 =2 , - st_yosemite =3 , - st_seq =4 , + st_yosemite =2 , + st_seq =3 ,PASSTHRU_REQ_TYPE =0x00000001 , PASSTHRU_REQ_NO_WAKEUP = 0x00000100,
@@ -196,7 +184,7 @@ struct req_msg {u8 data_dir;u8 payload_sz;/* payload size in 4-byte, not used */ u8 cdb[STEX_CDB_LENGTH ]; -u8 variable[REQ_VARIABLE_LEN ]; +u32 variable[0 ]; };struct status_msg {
@@ -252,12 +240,6 @@ struct st_drvver {u32 reserved[3 ]; }; -#define MU_REQ_BUFFER_SIZE (MU_REQ_COUNT * sizeof(struct req_msg)) -#define MU_STATUS_BUFFER_SIZE (MU_STATUS_COUNT * sizeof(struct status_msg)) -#define MU_BUFFER_SIZE (MU_REQ_BUFFER_SIZE + MU_STATUS_BUFFER_SIZE) -#define STEX_EXTRA_SIZE sizeof(struct st_frame) -#define STEX_BUFFER_SIZE (MU_BUFFER_SIZE + STEX_EXTRA_SIZE) -struct st_ccb {struct req_msg *req;struct scsi_cmnd *cmd;
@@ -288,13 +270,26 @@ struct st_hba {struct status_msg *status_buffer;void *copy_buffer;/* temp buffer for driver-handled commands */ -struct st_ccb ccb[MU_MAX_REQUEST ]; +struct st_ccb *ccb;struct st_ccb *wait_ccb;unsigned int mu_status;unsigned int cardtype;int msi_enabled;int out_req_cnt; +u32 extra_offset; +u16 rq_count; +u16 rq_size; +u16 sts_count; +}; + +struct st_card_info { +unsigned int max_id; +unsigned int max_lun; +unsigned int max_channel; +u16 rq_count; +u16 rq_size; +u16 sts_count; };static int msi;
@@ -331,7 +326,7 @@ static struct status_msg *stex_get_status(struct st_hba *hba)struct status_msg *status = hba->status_buffer + hba->status_tail; ++hba->status_tail; - hba->status_tail %=MU_STATUS_COUNT ; + hba->status_tail %= hba->sts_count+1 ;return status; }
@@ -349,11 +344,10 @@ static void stex_invalid_field(struct scsi_cmnd *cmd,static struct req_msg *stex_alloc_req (struct st_hba *hba) { -struct req_msg *req = ((struct req_msg *)hba->dma_mem) + - hba->req_head; +struct req_msg *req = hba->dma_mem + hba->req_head * hba->rq_size; ++hba->req_head; - hba->req_head %=MU_REQ_COUNT ; + hba->req_head %= hba->rq_count+1 ;return req; }
@@ -653,7 +647,7 @@ static void stex_mu_intr(struct st_hba *hba, u32 doorbell)/* status payloads */ hba->status_head =readl (base +OMR1 ); -if (unlikely (hba->status_head >=MU_STATUS_COUNT )) { +if (unlikely (hba->status_head > hba->sts_count)) { printk(KERN_WARNING DRV_NAME "(%s): invalid status head\n", pci_name(hba->pdev));return ;
@@ -789,19 +783,19 @@ static int stex_handshake(struct st_hba *hba) h = (struct handshake_frame *)hba->status_buffer; h->rb_phy =cpu_to_le64 (hba->dma_handle); - h->req_sz =cpu_to_le16 (sizeof (struct req_msg )); - h->req_cnt =cpu_to_le16 (MU_REQ_COUNT ); + h->req_sz =cpu_to_le16 (hba->rq_size); + h->req_cnt =cpu_to_le16 (hba->rq_count+1 ); h->status_sz =cpu_to_le16 (sizeof (struct status_msg )); - h->status_cnt =cpu_to_le16 (MU_STATUS_COUNT ); + h->status_cnt =cpu_to_le16 (hba->sts_count+1 );stex_gettime (&h->hosttime); h->partner_type =HMU_PARTNER_TYPE ; -if (hba->dma_size >STEX_BUFFER_SIZE ) { - h->extra_offset =cpu_to_le32 (STEX_BUFFER_SIZE ); +if (hba->extra_offset) { + h->extra_offset =cpu_to_le32 (hba->extra_offset); h->extra_size =cpu_to_le32 (ST_ADDITIONAL_MEM ); }else h->extra_offset = h->extra_size =0 ; - status_phys = hba->dma_handle +MU_REQ_BUFFER_SIZE ; + status_phys = hba->dma_handle + (hba->rq_count+1 ) * hba->rq_size;writel (status_phys, base +IMR0 );readl (base +IMR0 );writel ((status_phys >>16 ) >>16 , base +IMR1 );
@@ -1026,10 +1020,72 @@ static struct scsi_host_template driver_template = { .slave_destroy = stex_slave_destroy, .eh_abort_handler = stex_abort, .eh_host_reset_handler = stex_reset, - .can_queue = ST_CAN_QUEUE, .this_id = -1, .sg_tablesize = ST_MAX_SG, - .cmd_per_lun = ST_CMD_PER_LUN, +}; + +static struct pci_device_id stex_pci_tbl[] = { +/* st_shasta */ + {0x105a ,0x8350 ,PCI_ANY_ID ,PCI_ANY_ID ,0 ,0 , + st_shasta },/* SuperTrak EX8350/8300/16350/16300 */ + {0x105a ,0xc350 ,PCI_ANY_ID ,PCI_ANY_ID ,0 ,0 , + st_shasta },/* SuperTrak EX12350 */ + {0x105a ,0x4302 ,PCI_ANY_ID ,PCI_ANY_ID ,0 ,0 , + st_shasta },/* SuperTrak EX4350 */ + {0x105a ,0xe350 ,PCI_ANY_ID ,PCI_ANY_ID ,0 ,0 , + st_shasta },/* SuperTrak EX24350 */ + +/* st_vsc */ + {0x105a ,0x7250 ,PCI_ANY_ID ,PCI_ANY_ID ,0 ,0 , st_vsc }, + +/* st_yosemite */ + {0x105a ,0x8650 ,PCI_ANY_ID ,PCI_ANY_ID ,0 ,0 , st_yosemite }, + +/* st_seq */ + {0x105a ,0x3360 ,PCI_ANY_ID ,PCI_ANY_ID ,0 ,0 , st_seq }, + { }/* terminate list */ +}; + +static struct st_card_info stex_card_info[] = { +/* st_shasta */ + { + .max_id =17 , + .max_lun =8 , + .max_channel =0 , + .rq_count =32 , + .rq_size =1048 , + .sts_count =32 , + }, + +/* st_vsc */ + { + .max_id =129 , + .max_lun =1 , + .max_channel =0 , + .rq_count =32 , + .rq_size =1048 , + .sts_count =32 , + }, + +/* st_yosemite */ + { + .max_id =2 , + .max_lun =256 , + .max_channel =0 , + .rq_count =256 , + .rq_size =1048 , + .sts_count =256 , + }, + +/* st_seq */ + { + .max_id =129 , + .max_lun =1 , + .max_channel =0 , + .rq_count =32 , + .rq_size =1048 , + .sts_count =32 , + }, };static int stex_set_dma_mask (struct pci_dev * pdev)
@@ -1084,6 +1140,8 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id) {struct st_hba *hba;struct Scsi_Host *host; +const struct st_card_info *ci =NULL ; +u32 sts_offset, cp_offset;int err; err =pci_enable_device (pdev);
@@ -1127,10 +1185,15 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id) } hba->cardtype = (unsigned int ) id->driver_data; -if (hba->cardtype == st_vsc && (pdev->subsystem_device &1 )) - hba->cardtype = st_vsc1; - hba->dma_size = (hba->cardtype == st_vsc1 || hba->cardtype == st_seq) ? - (STEX_BUFFER_SIZE +ST_ADDITIONAL_MEM ) : (STEX_BUFFER_SIZE ); + ci = &stex_card_info[hba->cardtype]; + sts_offset = (ci->rq_count+1 ) * ci->rq_size; + cp_offset = sts_offset + (ci->sts_count+1 ) *sizeof (struct status_msg ); + hba->dma_size = cp_offset +sizeof (struct st_frame ); +if (hba->cardtype == st_seq || + (hba->cardtype == st_vsc && (pdev->subsystem_device &1 ))) { + hba->extra_offset = hba->dma_size; + hba->dma_size +=ST_ADDITIONAL_MEM ; + } hba->dma_mem =dma_alloc_coherent (&pdev->dev, hba->dma_size, &hba->dma_handle,GFP_KERNEL );if (!hba->dma_mem) {
@@ -1140,23 +1203,26 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id) goto out_iounmap; } - hba->status_buffer = - (struct status_msg *)(hba->dma_mem +MU_REQ_BUFFER_SIZE ); - hba->copy_buffer = hba->dma_mem +MU_BUFFER_SIZE ; + hba->ccb =kcalloc (ci->rq_count,sizeof (struct st_ccb ),GFP_KERNEL ); +if (!hba->ccb) { + err = -ENOMEM ; + printk(KERN_ERR DRV_NAME "(%s): ccb alloc failed\n", + pci_name(pdev)); + goto out_pci_free; + } + + hba->status_buffer = (struct status_msg *)(hba->dma_mem + sts_offset); + hba->copy_buffer = hba->dma_mem + cp_offset; + hba->rq_count = ci->rq_count; + hba->rq_size = ci->rq_size; + hba->sts_count = ci->sts_count; hba->mu_status =MU_STATE_STARTING ; -if (hba->cardtype == st_shasta) { - host->max_lun =8 ; - host->max_id =16 +1 ; - }else if (hba->cardtype == st_yosemite) { - host->max_lun =256 ; - host->max_id =1 +1 ; - }else { -/* st_vsc , st_vsc1 and st_seq */ - host->max_lun =1 ; - host->max_id =128 +1 ; - } - host->max_channel =0 ; + host->can_queue = ci->rq_count; + host->cmd_per_lun = ci->rq_count; + host->max_id = ci->max_id; + host->max_lun = ci->max_lun; + host->max_channel = ci->max_channel; host->unique_id = host->host_no; host->max_cmd_len =STEX_CDB_LENGTH ;
@@ -1167,7 +1233,7 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id)if (err) { printk(KERN_ERR DRV_NAME "(%s): request irq failed\n", pci_name(pdev)); - goto out_pci_free; + goto out_ccb_free; } err =stex_handshake (hba);
@@ -1196,6 +1262,8 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id) out_free_irq:stex_free_irq (hba); +out_ccb_free: +kfree (hba->ccb); out_pci_free:dma_free_coherent (&pdev->dev, hba->dma_size, hba->dma_mem, hba->dma_handle);
@@ -1260,6 +1328,8 @@ static void stex_hba_free(struct st_hba *hba)pci_release_regions (hba->pdev); +kfree (hba->ccb); +dma_free_coherent (&hba->pdev->dev, hba->dma_size, hba->dma_mem, hba->dma_handle); }
@@ -1288,27 +1358,6 @@ static void stex_shutdown(struct pci_dev *pdev)stex_hba_stop (hba); } -static struct pci_device_id stex_pci_tbl[] = { -/* st_shasta */ - {0x105a ,0x8350 ,PCI_ANY_ID ,PCI_ANY_ID ,0 ,0 , - st_shasta },/* SuperTrak EX8350/8300/16350/16300 */ - {0x105a ,0xc350 ,PCI_ANY_ID ,PCI_ANY_ID ,0 ,0 , - st_shasta },/* SuperTrak EX12350 */ - {0x105a ,0x4302 ,PCI_ANY_ID ,PCI_ANY_ID ,0 ,0 , - st_shasta },/* SuperTrak EX4350 */ - {0x105a ,0xe350 ,PCI_ANY_ID ,PCI_ANY_ID ,0 ,0 , - st_shasta },/* SuperTrak EX24350 */ - -/* st_vsc */ - {0x105a ,0x7250 ,PCI_ANY_ID ,PCI_ANY_ID ,0 ,0 , st_vsc }, - -/* st_yosemite */ - {0x105a ,0x8650 ,PCI_ANY_ID ,PCI_ANY_ID ,0 ,0 , st_yosemite }, - -/* st_seq */ - {0x105a ,0x3360 ,PCI_ANY_ID ,PCI_ANY_ID ,0 ,0 , st_seq }, - { }/* terminate list */ -};MODULE_DEVICE_TABLE (pci, stex_pci_tbl);static struct pci_driver stex_pci_driver = {