aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Rothwell <sfr@canb.auug.org.au>2019-01-18 12:50:43 +1100
committerStephen Rothwell <sfr@canb.auug.org.au>2019-01-18 12:50:43 +1100
commit14d1524d3d1c5bcfe5d715fdd28315651da77ae2 (patch)
tree95aed7a4eae5ce90b1dec3874a219c0e38f3a8c2
parentd4ab2653b04ecfa7f578fe4ff6f0dff868ef227c (diff)
parent6de89c8b7dbe6c0ef4adf10c78219adeb8c5fe76 (diff)
download96b-common-14d1524d3d1c5bcfe5d715fdd28315651da77ae2.tar.gz
Merge remote-tracking branch 'scsi/for-next'
-rw-r--r--drivers/scsi/Kconfig2
-rw-r--r--drivers/scsi/arcmsr/arcmsr.h13
-rw-r--r--drivers/scsi/arcmsr/arcmsr_hba.c332
-rw-r--r--drivers/scsi/bnx2i/bnx2i_iscsi.c2
-rw-r--r--drivers/scsi/gdth.c1286
-rw-r--r--drivers/scsi/gdth.h30
-rw-r--r--drivers/scsi/gdth_ioctl.h89
-rw-r--r--drivers/scsi/gdth_proc.c113
-rw-r--r--drivers/scsi/gdth_proc.h3
-rw-r--r--drivers/scsi/hisi_sas/hisi_sas.h47
-rw-r--r--drivers/scsi/hisi_sas/hisi_sas_main.c508
-rw-r--r--drivers/scsi/hisi_sas/hisi_sas_v2_hw.c9
-rw-r--r--drivers/scsi/hisi_sas/hisi_sas_v3_hw.c174
-rw-r--r--drivers/scsi/sd.c62
-rw-r--r--drivers/scsi/sd.h62
15 files changed, 1237 insertions, 1495 deletions
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index f38882f6f37d..4d5d79d56f4b 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -665,7 +665,7 @@ config SCSI_DMX3191D
config SCSI_GDTH
tristate "Intel/ICP (former GDT SCSI Disk Array) RAID Controller support"
- depends on (ISA || EISA || PCI) && SCSI && ISA_DMA_API
+ depends on PCI && SCSI
---help---
Formerly called GDT SCSI Disk Array Controller Support.
diff --git a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h
index 9c397a2794d6..a94c513a57d8 100644
--- a/drivers/scsi/arcmsr/arcmsr.h
+++ b/drivers/scsi/arcmsr/arcmsr.h
@@ -49,7 +49,7 @@ struct device_attribute;
#define ARCMSR_MAX_OUTSTANDING_CMD 1024
#define ARCMSR_DEFAULT_OUTSTANDING_CMD 128
#define ARCMSR_MIN_OUTSTANDING_CMD 32
-#define ARCMSR_DRIVER_VERSION "v1.40.00.09-20180709"
+#define ARCMSR_DRIVER_VERSION "v1.40.00.10-20181217"
#define ARCMSR_SCSI_INITIATOR_ID 255
#define ARCMSR_MAX_XFER_SECTORS 512
#define ARCMSR_MAX_XFER_SECTORS_B 4096
@@ -739,7 +739,7 @@ struct AdapterControlBlock
#define ACB_ADAPTER_TYPE_C 0x00000002 /* hbc L IOP */
#define ACB_ADAPTER_TYPE_D 0x00000003 /* hbd M IOP */
#define ACB_ADAPTER_TYPE_E 0x00000004 /* hba L IOP */
- u32 roundup_ccbsize;
+ u32 ioqueue_size;
struct pci_dev * pdev;
struct Scsi_Host * host;
unsigned long vir2phy_offset;
@@ -747,6 +747,7 @@ struct AdapterControlBlock
uint32_t outbound_int_enable;
uint32_t cdb_phyaddr_hi32;
uint32_t reg_mu_acc_handle0;
+ uint64_t cdb_phyadd_hipart;
spinlock_t eh_lock;
spinlock_t ccblist_lock;
spinlock_t postq_lock;
@@ -855,11 +856,11 @@ struct AdapterControlBlock
*******************************************************************************
*/
struct CommandControlBlock{
- /*x32:sizeof struct_CCB=(32+60)byte, x64:sizeof struct_CCB=(64+60)byte*/
+ /*x32:sizeof struct_CCB=(64+60)byte, x64:sizeof struct_CCB=(64+60)byte*/
struct list_head list; /*x32: 8byte, x64: 16byte*/
struct scsi_cmnd *pcmd; /*8 bytes pointer of linux scsi command */
struct AdapterControlBlock *acb; /*x32: 4byte, x64: 8byte*/
- uint32_t cdb_phyaddr; /*x32: 4byte, x64: 4byte*/
+ unsigned long cdb_phyaddr; /*x32: 4byte, x64: 8byte*/
uint32_t arc_cdb_size; /*x32:4byte,x64:4byte*/
uint16_t ccb_flags; /*x32: 2byte, x64: 2byte*/
#define CCB_FLAG_READ 0x0000
@@ -875,10 +876,10 @@ struct CommandControlBlock{
uint32_t smid;
#if BITS_PER_LONG == 64
/* ======================512+64 bytes======================== */
- uint32_t reserved[4]; /*16 byte*/
+ uint32_t reserved[3]; /*12 byte*/
#else
/* ======================512+32 bytes======================== */
- // uint32_t reserved; /*4 byte*/
+ uint32_t reserved[8]; /*32 byte*/
#endif
/* ======================================================= */
struct ARCMSR_CDB arcmsr_cdb;
diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
index 57c6fa388bf6..1100d110c225 100644
--- a/drivers/scsi/arcmsr/arcmsr_hba.c
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c
@@ -91,6 +91,10 @@ static int cmd_per_lun = ARCMSR_DEFAULT_CMD_PERLUN;
module_param(cmd_per_lun, int, S_IRUGO);
MODULE_PARM_DESC(cmd_per_lun, " device queue depth(1 ~ 128), default is 32");
+static int dma_mask_64 = 0;
+module_param(dma_mask_64, int, S_IRUGO);
+MODULE_PARM_DESC(dma_mask_64, " set DMA mask to 64 bits(0 ~ 1), dma_mask_64=1(64 bits), =0(32 bits)");
+
static int set_date_time = 0;
module_param(set_date_time, int, S_IRUGO);
MODULE_PARM_DESC(set_date_time, " send date, time to iop(0 ~ 1), set_date_time=1(enable), default(=0) is disable");
@@ -223,13 +227,13 @@ static struct pci_driver arcmsr_pci_driver = {
****************************************************************************
*/
-static void arcmsr_free_mu(struct AdapterControlBlock *acb)
+static void arcmsr_free_io_queue(struct AdapterControlBlock *acb)
{
switch (acb->adapter_type) {
case ACB_ADAPTER_TYPE_B:
case ACB_ADAPTER_TYPE_D:
case ACB_ADAPTER_TYPE_E: {
- dma_free_coherent(&acb->pdev->dev, acb->roundup_ccbsize,
+ dma_free_coherent(&acb->pdev->dev, acb->ioqueue_size,
acb->dma_coherent2, acb->dma_coherent_handle2);
break;
}
@@ -576,6 +580,58 @@ static void arcmsr_flush_adapter_cache(struct AdapterControlBlock *acb)
}
}
+static void arcmsr_hbaB_assign_regAddr(struct AdapterControlBlock *acb)
+{
+ struct MessageUnit_B *reg = acb->pmuB;
+
+ if (acb->pdev->device == PCI_DEVICE_ID_ARECA_1203) {
+ reg->drv2iop_doorbell = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL_1203);
+ reg->drv2iop_doorbell_mask = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL_MASK_1203);
+ reg->iop2drv_doorbell = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL_1203);
+ reg->iop2drv_doorbell_mask = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL_MASK_1203);
+ } else {
+ reg->drv2iop_doorbell= MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL);
+ reg->drv2iop_doorbell_mask = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL_MASK);
+ reg->iop2drv_doorbell = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL);
+ reg->iop2drv_doorbell_mask = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL_MASK);
+ }
+ reg->message_wbuffer = MEM_BASE1(ARCMSR_MESSAGE_WBUFFER);
+ reg->message_rbuffer = MEM_BASE1(ARCMSR_MESSAGE_RBUFFER);
+ reg->message_rwbuffer = MEM_BASE1(ARCMSR_MESSAGE_RWBUFFER);
+}
+
+static void arcmsr_hbaD_assign_regAddr(struct AdapterControlBlock *acb)
+{
+ struct MessageUnit_D *reg = acb->pmuD;
+
+ reg->chip_id = MEM_BASE0(ARCMSR_ARC1214_CHIP_ID);
+ reg->cpu_mem_config = MEM_BASE0(ARCMSR_ARC1214_CPU_MEMORY_CONFIGURATION);
+ reg->i2o_host_interrupt_mask = MEM_BASE0(ARCMSR_ARC1214_I2_HOST_INTERRUPT_MASK);
+ reg->sample_at_reset = MEM_BASE0(ARCMSR_ARC1214_SAMPLE_RESET);
+ reg->reset_request = MEM_BASE0(ARCMSR_ARC1214_RESET_REQUEST);
+ reg->host_int_status = MEM_BASE0(ARCMSR_ARC1214_MAIN_INTERRUPT_STATUS);
+ reg->pcief0_int_enable = MEM_BASE0(ARCMSR_ARC1214_PCIE_F0_INTERRUPT_ENABLE);
+ reg->inbound_msgaddr0 = MEM_BASE0(ARCMSR_ARC1214_INBOUND_MESSAGE0);
+ reg->inbound_msgaddr1 = MEM_BASE0(ARCMSR_ARC1214_INBOUND_MESSAGE1);
+ reg->outbound_msgaddr0 = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_MESSAGE0);
+ reg->outbound_msgaddr1 = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_MESSAGE1);
+ reg->inbound_doorbell = MEM_BASE0(ARCMSR_ARC1214_INBOUND_DOORBELL);
+ reg->outbound_doorbell = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_DOORBELL);
+ reg->outbound_doorbell_enable = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_DOORBELL_ENABLE);
+ reg->inboundlist_base_low = MEM_BASE0(ARCMSR_ARC1214_INBOUND_LIST_BASE_LOW);
+ reg->inboundlist_base_high = MEM_BASE0(ARCMSR_ARC1214_INBOUND_LIST_BASE_HIGH);
+ reg->inboundlist_write_pointer = MEM_BASE0(ARCMSR_ARC1214_INBOUND_LIST_WRITE_POINTER);
+ reg->outboundlist_base_low = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LIST_BASE_LOW);
+ reg->outboundlist_base_high = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LIST_BASE_HIGH);
+ reg->outboundlist_copy_pointer = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LIST_COPY_POINTER);
+ reg->outboundlist_read_pointer = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LIST_READ_POINTER);
+ reg->outboundlist_interrupt_cause = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_INTERRUPT_CAUSE);
+ reg->outboundlist_interrupt_enable = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_INTERRUPT_ENABLE);
+ reg->message_wbuffer = MEM_BASE0(ARCMSR_ARC1214_MESSAGE_WBUFFER);
+ reg->message_rbuffer = MEM_BASE0(ARCMSR_ARC1214_MESSAGE_RBUFFER);
+ reg->msgcode_rwbuffer = MEM_BASE0(ARCMSR_ARC1214_MESSAGE_RWBUFFER);
+}
+
static bool arcmsr_alloc_io_queue(struct AdapterControlBlock *acb)
{
bool rtn = true;
@@ -585,10 +641,9 @@ static bool arcmsr_alloc_io_queue(struct AdapterControlBlock *acb)
switch (acb->adapter_type) {
case ACB_ADAPTER_TYPE_B: {
- struct MessageUnit_B *reg;
- acb->roundup_ccbsize = roundup(sizeof(struct MessageUnit_B), 32);
+ acb->ioqueue_size = roundup(sizeof(struct MessageUnit_B), 32);
dma_coherent = dma_alloc_coherent(&pdev->dev,
- acb->roundup_ccbsize,
+ acb->ioqueue_size,
&dma_coherent_handle,
GFP_KERNEL);
if (!dma_coherent) {
@@ -597,30 +652,14 @@ static bool arcmsr_alloc_io_queue(struct AdapterControlBlock *acb)
}
acb->dma_coherent_handle2 = dma_coherent_handle;
acb->dma_coherent2 = dma_coherent;
- reg = (struct MessageUnit_B *)dma_coherent;
- acb->pmuB = reg;
- if (acb->pdev->device == PCI_DEVICE_ID_ARECA_1203) {
- reg->drv2iop_doorbell = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL_1203);
- reg->drv2iop_doorbell_mask = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL_MASK_1203);
- reg->iop2drv_doorbell = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL_1203);
- reg->iop2drv_doorbell_mask = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL_MASK_1203);
- } else {
- reg->drv2iop_doorbell = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL);
- reg->drv2iop_doorbell_mask = MEM_BASE0(ARCMSR_DRV2IOP_DOORBELL_MASK);
- reg->iop2drv_doorbell = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL);
- reg->iop2drv_doorbell_mask = MEM_BASE0(ARCMSR_IOP2DRV_DOORBELL_MASK);
- }
- reg->message_wbuffer = MEM_BASE1(ARCMSR_MESSAGE_WBUFFER);
- reg->message_rbuffer = MEM_BASE1(ARCMSR_MESSAGE_RBUFFER);
- reg->message_rwbuffer = MEM_BASE1(ARCMSR_MESSAGE_RWBUFFER);
+ acb->pmuB = (struct MessageUnit_B *)dma_coherent;
+ arcmsr_hbaB_assign_regAddr(acb);
}
break;
case ACB_ADAPTER_TYPE_D: {
- struct MessageUnit_D *reg;
-
- acb->roundup_ccbsize = roundup(sizeof(struct MessageUnit_D), 32);
+ acb->ioqueue_size = roundup(sizeof(struct MessageUnit_D), 32);
dma_coherent = dma_alloc_coherent(&pdev->dev,
- acb->roundup_ccbsize,
+ acb->ioqueue_size,
&dma_coherent_handle,
GFP_KERNEL);
if (!dma_coherent) {
@@ -629,42 +668,16 @@ static bool arcmsr_alloc_io_queue(struct AdapterControlBlock *acb)
}
acb->dma_coherent_handle2 = dma_coherent_handle;
acb->dma_coherent2 = dma_coherent;
- reg = (struct MessageUnit_D *)dma_coherent;
- acb->pmuD = reg;
- reg->chip_id = MEM_BASE0(ARCMSR_ARC1214_CHIP_ID);
- reg->cpu_mem_config = MEM_BASE0(ARCMSR_ARC1214_CPU_MEMORY_CONFIGURATION);
- reg->i2o_host_interrupt_mask = MEM_BASE0(ARCMSR_ARC1214_I2_HOST_INTERRUPT_MASK);
- reg->sample_at_reset = MEM_BASE0(ARCMSR_ARC1214_SAMPLE_RESET);
- reg->reset_request = MEM_BASE0(ARCMSR_ARC1214_RESET_REQUEST);
- reg->host_int_status = MEM_BASE0(ARCMSR_ARC1214_MAIN_INTERRUPT_STATUS);
- reg->pcief0_int_enable = MEM_BASE0(ARCMSR_ARC1214_PCIE_F0_INTERRUPT_ENABLE);
- reg->inbound_msgaddr0 = MEM_BASE0(ARCMSR_ARC1214_INBOUND_MESSAGE0);
- reg->inbound_msgaddr1 = MEM_BASE0(ARCMSR_ARC1214_INBOUND_MESSAGE1);
- reg->outbound_msgaddr0 = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_MESSAGE0);
- reg->outbound_msgaddr1 = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_MESSAGE1);
- reg->inbound_doorbell = MEM_BASE0(ARCMSR_ARC1214_INBOUND_DOORBELL);
- reg->outbound_doorbell = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_DOORBELL);
- reg->outbound_doorbell_enable = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_DOORBELL_ENABLE);
- reg->inboundlist_base_low = MEM_BASE0(ARCMSR_ARC1214_INBOUND_LIST_BASE_LOW);
- reg->inboundlist_base_high = MEM_BASE0(ARCMSR_ARC1214_INBOUND_LIST_BASE_HIGH);
- reg->inboundlist_write_pointer = MEM_BASE0(ARCMSR_ARC1214_INBOUND_LIST_WRITE_POINTER);
- reg->outboundlist_base_low = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LIST_BASE_LOW);
- reg->outboundlist_base_high = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LIST_BASE_HIGH);
- reg->outboundlist_copy_pointer = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LIST_COPY_POINTER);
- reg->outboundlist_read_pointer = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_LIST_READ_POINTER);
- reg->outboundlist_interrupt_cause = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_INTERRUPT_CAUSE);
- reg->outboundlist_interrupt_enable = MEM_BASE0(ARCMSR_ARC1214_OUTBOUND_INTERRUPT_ENABLE);
- reg->message_wbuffer = MEM_BASE0(ARCMSR_ARC1214_MESSAGE_WBUFFER);
- reg->message_rbuffer = MEM_BASE0(ARCMSR_ARC1214_MESSAGE_RBUFFER);
- reg->msgcode_rwbuffer = MEM_BASE0(ARCMSR_ARC1214_MESSAGE_RWBUFFER);
+ acb->pmuD = (struct MessageUnit_D *)dma_coherent;
+ arcmsr_hbaD_assign_regAddr(acb);
}
break;
case ACB_ADAPTER_TYPE_E: {
uint32_t completeQ_size;
completeQ_size = sizeof(struct deliver_completeQ) * ARCMSR_MAX_HBE_DONEQUEUE + 128;
- acb->roundup_ccbsize = roundup(completeQ_size, 32);
+ acb->ioqueue_size = roundup(completeQ_size, 32);
dma_coherent = dma_alloc_coherent(&pdev->dev,
- acb->roundup_ccbsize,
+ acb->ioqueue_size,
&dma_coherent_handle,
GFP_KERNEL);
if (!dma_coherent){
@@ -674,7 +687,7 @@ static bool arcmsr_alloc_io_queue(struct AdapterControlBlock *acb)
acb->dma_coherent_handle2 = dma_coherent_handle;
acb->dma_coherent2 = dma_coherent;
acb->pCompletionQ = dma_coherent;
- acb->completionQ_entry = acb->roundup_ccbsize / sizeof(struct deliver_completeQ);
+ acb->completionQ_entry = acb->ioqueue_size / sizeof(struct deliver_completeQ);
acb->doneq_index = 0;
}
break;
@@ -691,11 +704,11 @@ static int arcmsr_alloc_ccb_pool(struct AdapterControlBlock *acb)
dma_addr_t dma_coherent_handle;
struct CommandControlBlock *ccb_tmp;
int i = 0, j = 0;
- dma_addr_t cdb_phyaddr;
+ unsigned long cdb_phyaddr, next_ccb_phy;
unsigned long roundup_ccbsize;
unsigned long max_xfer_len;
unsigned long max_sg_entrys;
- uint32_t firm_config_version;
+ uint32_t firm_config_version, curr_phy_upper32;
for (i = 0; i < ARCMSR_MAX_TARGETID; i++)
for (j = 0; j < ARCMSR_MAX_TARGETLUN; j++)
@@ -712,6 +725,7 @@ static int arcmsr_alloc_ccb_pool(struct AdapterControlBlock *acb)
acb->host->sg_tablesize = max_sg_entrys;
roundup_ccbsize = roundup(sizeof(struct CommandControlBlock) + (max_sg_entrys - 1) * sizeof(struct SG64ENTRY), 32);
acb->uncache_size = roundup_ccbsize * acb->maxFreeCCB;
+ acb->uncache_size += acb->ioqueue_size;
dma_coherent = dma_alloc_coherent(&pdev->dev, acb->uncache_size, &dma_coherent_handle, GFP_KERNEL);
if(!dma_coherent){
printk(KERN_NOTICE "arcmsr%d: dma_alloc_coherent got error\n", acb->host->host_no);
@@ -722,9 +736,10 @@ static int arcmsr_alloc_ccb_pool(struct AdapterControlBlock *acb)
memset(dma_coherent, 0, acb->uncache_size);
acb->ccbsize = roundup_ccbsize;
ccb_tmp = dma_coherent;
+ curr_phy_upper32 = upper_32_bits(dma_coherent_handle);
acb->vir2phy_offset = (unsigned long)dma_coherent - (unsigned long)dma_coherent_handle;
for(i = 0; i < acb->maxFreeCCB; i++){
- cdb_phyaddr = dma_coherent_handle + offsetof(struct CommandControlBlock, arcmsr_cdb);
+ cdb_phyaddr = (unsigned long)dma_coherent_handle + offsetof(struct CommandControlBlock, arcmsr_cdb);
switch (acb->adapter_type) {
case ACB_ADAPTER_TYPE_A:
case ACB_ADAPTER_TYPE_B:
@@ -740,10 +755,34 @@ static int arcmsr_alloc_ccb_pool(struct AdapterControlBlock *acb)
ccb_tmp->acb = acb;
ccb_tmp->smid = (u32)i << 16;
INIT_LIST_HEAD(&ccb_tmp->list);
- list_add_tail(&ccb_tmp->list, &acb->ccb_free_list);
+ next_ccb_phy = dma_coherent_handle + roundup_ccbsize;
+ if (upper_32_bits(next_ccb_phy) != curr_phy_upper32) {
+ acb->maxFreeCCB = i;
+ acb->host->can_queue = i;
+ break;
+ }
+ else
+ list_add_tail(&ccb_tmp->list, &acb->ccb_free_list);
ccb_tmp = (struct CommandControlBlock *)((unsigned long)ccb_tmp + roundup_ccbsize);
- dma_coherent_handle = dma_coherent_handle + roundup_ccbsize;
+ dma_coherent_handle = next_ccb_phy;
}
+ acb->dma_coherent_handle2 = dma_coherent_handle;
+ acb->dma_coherent2 = ccb_tmp;
+ switch (acb->adapter_type) {
+ case ACB_ADAPTER_TYPE_B:
+ acb->pmuB = (struct MessageUnit_B *)acb->dma_coherent2;
+ arcmsr_hbaB_assign_regAddr(acb);
+ break;
+ case ACB_ADAPTER_TYPE_D:
+ acb->pmuD = (struct MessageUnit_D *)acb->dma_coherent2;
+ arcmsr_hbaD_assign_regAddr(acb);
+ break;
+ case ACB_ADAPTER_TYPE_E:
+ acb->pCompletionQ = acb->dma_coherent2;
+ acb->completionQ_entry = acb->ioqueue_size / sizeof(struct deliver_completeQ);
+ acb->doneq_index = 0;
+ break;
+ }
return 0;
}
@@ -894,6 +933,31 @@ static void arcmsr_init_set_datetime_timer(struct AdapterControlBlock *pacb)
add_timer(&pacb->refresh_timer);
}
+static int arcmsr_set_dma_mask(struct AdapterControlBlock *acb)
+{
+ struct pci_dev *pcidev = acb->pdev;
+
+ if (IS_DMA64) {
+ if (((acb->adapter_type == ACB_ADAPTER_TYPE_A) && !dma_mask_64) ||
+ dma_set_mask(&pcidev->dev, DMA_BIT_MASK(64)))
+ goto dma32;
+ if (dma_set_coherent_mask(&pcidev->dev, DMA_BIT_MASK(64)) ||
+ dma_set_mask_and_coherent(&pcidev->dev, DMA_BIT_MASK(64))) {
+ printk("arcmsr: set DMA 64 mask failed\n");
+ return -ENXIO;
+ }
+ } else {
+dma32:
+ if (dma_set_mask(&pcidev->dev, DMA_BIT_MASK(32)) ||
+ dma_set_coherent_mask(&pcidev->dev, DMA_BIT_MASK(32)) ||
+ dma_set_mask_and_coherent(&pcidev->dev, DMA_BIT_MASK(32))) {
+ printk("arcmsr: set DMA 32-bit mask failed\n");
+ return -ENXIO;
+ }
+ }
+ return 0;
+}
+
static int arcmsr_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
struct Scsi_Host *host;
@@ -908,22 +972,15 @@ static int arcmsr_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if(!host){
goto pci_disable_dev;
}
- error = dma_set_mask(&pdev->dev, DMA_BIT_MASK(64));
- if(error){
- error = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
- if(error){
- printk(KERN_WARNING
- "scsi%d: No suitable DMA mask available\n",
- host->host_no);
- goto scsi_host_release;
- }
- }
init_waitqueue_head(&wait_q);
bus = pdev->bus->number;
dev_fun = pdev->devfn;
acb = (struct AdapterControlBlock *) host->hostdata;
memset(acb,0,sizeof(struct AdapterControlBlock));
acb->pdev = pdev;
+ acb->adapter_type = id->driver_data;
+ if (arcmsr_set_dma_mask(acb))
+ goto scsi_host_release;
acb->host = host;
host->max_lun = ARCMSR_MAX_TARGETLUN;
host->max_id = ARCMSR_MAX_TARGETID; /*16:8*/
@@ -953,7 +1010,6 @@ static int arcmsr_probe(struct pci_dev *pdev, const struct pci_device_id *id)
ACB_F_MESSAGE_WQBUFFER_READED);
acb->acb_flags &= ~ACB_F_SCSISTOPADAPTER;
INIT_LIST_HEAD(&acb->ccb_free_list);
- acb->adapter_type = id->driver_data;
error = arcmsr_remap_pciregion(acb);
if(!error){
goto pci_release_regs;
@@ -965,9 +1021,10 @@ static int arcmsr_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if(!error){
goto free_hbb_mu;
}
+ arcmsr_free_io_queue(acb);
error = arcmsr_alloc_ccb_pool(acb);
if(error){
- goto free_hbb_mu;
+ goto unmap_pci_region;
}
error = scsi_add_host(host, &pdev->dev);
if(error){
@@ -995,8 +1052,9 @@ scsi_host_remove:
scsi_remove_host(host);
free_ccb_pool:
arcmsr_free_ccb_pool(acb);
+ goto unmap_pci_region;
free_hbb_mu:
- arcmsr_free_mu(acb);
+ arcmsr_free_io_queue(acb);
unmap_pci_region:
arcmsr_unmap_pciregion(acb);
pci_release_regs:
@@ -1042,7 +1100,6 @@ static int arcmsr_suspend(struct pci_dev *pdev, pm_message_t state)
static int arcmsr_resume(struct pci_dev *pdev)
{
- int error;
struct Scsi_Host *host = pci_get_drvdata(pdev);
struct AdapterControlBlock *acb =
(struct AdapterControlBlock *)host->hostdata;
@@ -1054,24 +1111,26 @@ static int arcmsr_resume(struct pci_dev *pdev)
pr_warn("%s: pci_enable_device error\n", __func__);
return -ENODEV;
}
- error = dma_set_mask(&pdev->dev, DMA_BIT_MASK(64));
- if (error) {
- error = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
- if (error) {
- pr_warn("scsi%d: No suitable DMA mask available\n",
- host->host_no);
- goto controller_unregister;
- }
- }
+ if (arcmsr_set_dma_mask(acb))
+ goto controller_unregister;
pci_set_master(pdev);
if (arcmsr_request_irq(pdev, acb) == FAILED)
goto controller_stop;
- if (acb->adapter_type == ACB_ADAPTER_TYPE_E) {
+ switch (acb->adapter_type) {
+ case ACB_ADAPTER_TYPE_B: {
+ struct MessageUnit_B *reg = acb->pmuB;
+ reg->post_qbuffer[0] = 0;
+ reg->postq_index = 0;
+ reg->doneq_index = 0;
+ break;
+ }
+ case ACB_ADAPTER_TYPE_E:
writel(0, &acb->pmuE->host_int_status);
writel(ARCMSR_HBEMU_DOORBELL_SYNC, &acb->pmuE->iobound_doorbell);
acb->in_doorbell = 0;
acb->out_doorbell = 0;
acb->doneq_index = 0;
+ break;
}
arcmsr_iop_init(acb);
arcmsr_init_get_devmap_timer(acb);
@@ -1351,10 +1410,12 @@ static void arcmsr_drain_donequeue(struct AdapterControlBlock *acb, struct Comma
static void arcmsr_done4abort_postqueue(struct AdapterControlBlock *acb)
{
int i = 0;
- uint32_t flag_ccb, ccb_cdb_phy;
+ uint32_t flag_ccb;
struct ARCMSR_CDB *pARCMSR_CDB;
bool error;
struct CommandControlBlock *pCCB;
+ unsigned long ccb_cdb_phy, cdb_phy_hipart;
+
switch (acb->adapter_type) {
case ACB_ADAPTER_TYPE_A: {
@@ -1366,7 +1427,10 @@ static void arcmsr_done4abort_postqueue(struct AdapterControlBlock *acb)
writel(outbound_intstatus, &reg->outbound_intstatus);/*clear interrupt*/
while(((flag_ccb = readl(&reg->outbound_queueport)) != 0xFFFFFFFF)
&& (i++ < acb->maxOutstanding)) {
- pARCMSR_CDB = (struct ARCMSR_CDB *)(acb->vir2phy_offset + (flag_ccb << 5));/*frame must be 32 bytes aligned*/
+ ccb_cdb_phy = (flag_ccb << 5) & 0xffffffff;
+ if (acb->cdb_phyadd_hipart)
+ ccb_cdb_phy = ccb_cdb_phy | acb->cdb_phyadd_hipart;
+ pARCMSR_CDB = (struct ARCMSR_CDB *)(acb->vir2phy_offset + ccb_cdb_phy);
pCCB = container_of(pARCMSR_CDB, struct CommandControlBlock, arcmsr_cdb);
error = (flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR_MODE0) ? true : false;
arcmsr_drain_donequeue(acb, pCCB, error);
@@ -1382,7 +1446,10 @@ static void arcmsr_done4abort_postqueue(struct AdapterControlBlock *acb)
flag_ccb = reg->done_qbuffer[i];
if (flag_ccb != 0) {
reg->done_qbuffer[i] = 0;
- pARCMSR_CDB = (struct ARCMSR_CDB *)(acb->vir2phy_offset+(flag_ccb << 5));/*frame must be 32 bytes aligned*/
+ ccb_cdb_phy = (flag_ccb << 5) & 0xffffffff;
+ if (acb->cdb_phyadd_hipart)
+ ccb_cdb_phy = ccb_cdb_phy | acb->cdb_phyadd_hipart;
+ pARCMSR_CDB = (struct ARCMSR_CDB *)(acb->vir2phy_offset + ccb_cdb_phy);
pCCB = container_of(pARCMSR_CDB, struct CommandControlBlock, arcmsr_cdb);
error = (flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR_MODE0) ? true : false;
arcmsr_drain_donequeue(acb, pCCB, error);
@@ -1399,7 +1466,9 @@ static void arcmsr_done4abort_postqueue(struct AdapterControlBlock *acb)
/*need to do*/
flag_ccb = readl(&reg->outbound_queueport_low);
ccb_cdb_phy = (flag_ccb & 0xFFFFFFF0);
- pARCMSR_CDB = (struct ARCMSR_CDB *)(acb->vir2phy_offset+ccb_cdb_phy);/*frame must be 32 bytes aligned*/
+ if (acb->cdb_phyadd_hipart)
+ ccb_cdb_phy = ccb_cdb_phy | acb->cdb_phyadd_hipart;
+ pARCMSR_CDB = (struct ARCMSR_CDB *)(acb->vir2phy_offset + ccb_cdb_phy);
pCCB = container_of(pARCMSR_CDB, struct CommandControlBlock, arcmsr_cdb);
error = (flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR_MODE1) ? true : false;
arcmsr_drain_donequeue(acb, pCCB, error);
@@ -1427,9 +1496,13 @@ static void arcmsr_done4abort_postqueue(struct AdapterControlBlock *acb)
((toggle ^ 0x4000) + 1);
doneq_index = pmu->doneq_index;
spin_unlock_irqrestore(&acb->doneq_lock, flags);
+ cdb_phy_hipart = pmu->done_qbuffer[doneq_index &
+ 0xFFF].addressHigh;
addressLow = pmu->done_qbuffer[doneq_index &
0xFFF].addressLow;
ccb_cdb_phy = (addressLow & 0xFFFFFFF0);
+ if (acb->cdb_phyadd_hipart)
+ ccb_cdb_phy = ccb_cdb_phy | acb->cdb_phyadd_hipart;
pARCMSR_CDB = (struct ARCMSR_CDB *)
(acb->vir2phy_offset + ccb_cdb_phy);
pCCB = container_of(pARCMSR_CDB,
@@ -1506,7 +1579,6 @@ static void arcmsr_free_pcidev(struct AdapterControlBlock *acb)
pdev = acb->pdev;
arcmsr_free_irq(pdev, acb);
arcmsr_free_ccb_pool(acb);
- arcmsr_free_mu(acb);
arcmsr_unmap_pciregion(acb);
pci_release_regions(pdev);
scsi_host_put(host);
@@ -1564,7 +1636,6 @@ static void arcmsr_remove(struct pci_dev *pdev)
}
arcmsr_free_irq(pdev, acb);
arcmsr_free_ccb_pool(acb);
- arcmsr_free_mu(acb);
arcmsr_unmap_pciregion(acb);
pci_release_regions(pdev);
scsi_host_put(host);
@@ -1749,12 +1820,8 @@ static void arcmsr_post_ccb(struct AdapterControlBlock *acb, struct CommandContr
arc_cdb_size = (ccb->arc_cdb_size > 0x300) ? 0x300 : ccb->arc_cdb_size;
ccb_post_stamp = (cdb_phyaddr | ((arc_cdb_size - 1) >> 6) | 1);
- if (acb->cdb_phyaddr_hi32) {
- writel(acb->cdb_phyaddr_hi32, &phbcmu->inbound_queueport_high);
- writel(ccb_post_stamp, &phbcmu->inbound_queueport_low);
- } else {
- writel(ccb_post_stamp, &phbcmu->inbound_queueport_low);
- }
+ writel(upper_32_bits(ccb->cdb_phyaddr), &phbcmu->inbound_queueport_high);
+ writel(ccb_post_stamp, &phbcmu->inbound_queueport_low);
}
break;
case ACB_ADAPTER_TYPE_D: {
@@ -1767,8 +1834,8 @@ static void arcmsr_post_ccb(struct AdapterControlBlock *acb, struct CommandContr
spin_lock_irqsave(&acb->postq_lock, flags);
postq_index = pmu->postq_index;
pinbound_srb = (struct InBound_SRB *)&(pmu->post_qbuffer[postq_index & 0xFF]);
- pinbound_srb->addressHigh = dma_addr_hi32(cdb_phyaddr);
- pinbound_srb->addressLow = dma_addr_lo32(cdb_phyaddr);
+ pinbound_srb->addressHigh = upper_32_bits(ccb->cdb_phyaddr);
+ pinbound_srb->addressLow = cdb_phyaddr;
pinbound_srb->length = ccb->arc_cdb_size >> 2;
arcmsr_cdb->msgContext = dma_addr_lo32(cdb_phyaddr);
toggle = postq_index & 0x4000;
@@ -2304,8 +2371,13 @@ static void arcmsr_hbaA_postqueue_isr(struct AdapterControlBlock *acb)
struct ARCMSR_CDB *pARCMSR_CDB;
struct CommandControlBlock *pCCB;
bool error;
+ unsigned long cdb_phy_addr;
+
while ((flag_ccb = readl(&reg->outbound_queueport)) != 0xFFFFFFFF) {
- pARCMSR_CDB = (struct ARCMSR_CDB *)(acb->vir2phy_offset + (flag_ccb << 5));/*frame must be 32 bytes aligned*/
+ cdb_phy_addr = (flag_ccb << 5) & 0xffffffff;
+ if (acb->cdb_phyadd_hipart)
+ cdb_phy_addr = cdb_phy_addr | acb->cdb_phyadd_hipart;
+ pARCMSR_CDB = (struct ARCMSR_CDB *)(acb->vir2phy_offset + cdb_phy_addr);
pCCB = container_of(pARCMSR_CDB, struct CommandControlBlock, arcmsr_cdb);
error = (flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR_MODE0) ? true : false;
arcmsr_drain_donequeue(acb, pCCB, error);
@@ -2319,13 +2391,18 @@ static void arcmsr_hbaB_postqueue_isr(struct AdapterControlBlock *acb)
struct ARCMSR_CDB *pARCMSR_CDB;
struct CommandControlBlock *pCCB;
bool error;
+ unsigned long cdb_phy_addr;
+
index = reg->doneq_index;
while ((flag_ccb = reg->done_qbuffer[index]) != 0) {
- reg->done_qbuffer[index] = 0;
- pARCMSR_CDB = (struct ARCMSR_CDB *)(acb->vir2phy_offset+(flag_ccb << 5));/*frame must be 32 bytes aligned*/
+ cdb_phy_addr = (flag_ccb << 5) & 0xffffffff;
+ if (acb->cdb_phyadd_hipart)
+ cdb_phy_addr = cdb_phy_addr | acb->cdb_phyadd_hipart;
+ pARCMSR_CDB = (struct ARCMSR_CDB *)(acb->vir2phy_offset + cdb_phy_addr);
pCCB = container_of(pARCMSR_CDB, struct CommandControlBlock, arcmsr_cdb);
error = (flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR_MODE0) ? true : false;
arcmsr_drain_donequeue(acb, pCCB, error);
+ reg->done_qbuffer[index] = 0;
index++;
index %= ARCMSR_MAX_HBB_POSTQUEUE;
reg->doneq_index = index;
@@ -2337,7 +2414,8 @@ static void arcmsr_hbaC_postqueue_isr(struct AdapterControlBlock *acb)
struct MessageUnit_C __iomem *phbcmu;
struct ARCMSR_CDB *arcmsr_cdb;
struct CommandControlBlock *ccb;
- uint32_t flag_ccb, ccb_cdb_phy, throttling = 0;
+ uint32_t flag_ccb, throttling = 0;
+ unsigned long ccb_cdb_phy;
int error;
phbcmu = acb->pmuC;
@@ -2347,6 +2425,8 @@ static void arcmsr_hbaC_postqueue_isr(struct AdapterControlBlock *acb)
while ((flag_ccb = readl(&phbcmu->outbound_queueport_low)) !=
0xFFFFFFFF) {
ccb_cdb_phy = (flag_ccb & 0xFFFFFFF0);
+ if (acb->cdb_phyadd_hipart)
+ ccb_cdb_phy = ccb_cdb_phy | acb->cdb_phyadd_hipart;
arcmsr_cdb = (struct ARCMSR_CDB *)(acb->vir2phy_offset
+ ccb_cdb_phy);
ccb = container_of(arcmsr_cdb, struct CommandControlBlock,
@@ -2367,12 +2447,12 @@ static void arcmsr_hbaC_postqueue_isr(struct AdapterControlBlock *acb)
static void arcmsr_hbaD_postqueue_isr(struct AdapterControlBlock *acb)
{
u32 outbound_write_pointer, doneq_index, index_stripped, toggle;
- uint32_t addressLow, ccb_cdb_phy;
+ uint32_t addressLow;
int error;
struct MessageUnit_D *pmu;
struct ARCMSR_CDB *arcmsr_cdb;
struct CommandControlBlock *ccb;
- unsigned long flags;
+ unsigned long flags, ccb_cdb_phy, cdb_phy_hipart;
spin_lock_irqsave(&acb->doneq_lock, flags);
pmu = acb->pmuD;
@@ -2386,9 +2466,13 @@ static void arcmsr_hbaD_postqueue_isr(struct AdapterControlBlock *acb)
pmu->doneq_index = index_stripped ? (index_stripped | toggle) :
((toggle ^ 0x4000) + 1);
doneq_index = pmu->doneq_index;
+ cdb_phy_hipart = pmu->done_qbuffer[doneq_index &
+ 0xFFF].addressHigh;
addressLow = pmu->done_qbuffer[doneq_index &
0xFFF].addressLow;
ccb_cdb_phy = (addressLow & 0xFFFFFFF0);
+ if (acb->cdb_phyadd_hipart)
+ ccb_cdb_phy = ccb_cdb_phy | acb->cdb_phyadd_hipart;
arcmsr_cdb = (struct ARCMSR_CDB *)(acb->vir2phy_offset
+ ccb_cdb_phy);
ccb = container_of(arcmsr_cdb,
@@ -3229,7 +3313,9 @@ static int arcmsr_hbaA_polling_ccbdone(struct AdapterControlBlock *acb,
uint32_t flag_ccb, outbound_intstatus, poll_ccb_done = 0, poll_count = 0;
int rtn;
bool error;
- polling_hba_ccb_retry:
+ unsigned long ccb_cdb_phy;
+
+polling_hba_ccb_retry:
poll_count++;
outbound_intstatus = readl(&reg->outbound_intstatus) & acb->outbound_int_enable;
writel(outbound_intstatus, &reg->outbound_intstatus);/*clear interrupt*/
@@ -3247,7 +3333,10 @@ static int arcmsr_hbaA_polling_ccbdone(struct AdapterControlBlock *acb,
goto polling_hba_ccb_retry;
}
}
- arcmsr_cdb = (struct ARCMSR_CDB *)(acb->vir2phy_offset + (flag_ccb << 5));
+ ccb_cdb_phy = (flag_ccb << 5) & 0xffffffff;
+ if (acb->cdb_phyadd_hipart)
+ ccb_cdb_phy = ccb_cdb_phy | acb->cdb_phyadd_hipart;
+ arcmsr_cdb = (struct ARCMSR_CDB *)(acb->vir2phy_offset + ccb_cdb_phy);
ccb = container_of(arcmsr_cdb, struct CommandControlBlock, arcmsr_cdb);
poll_ccb_done |= (ccb == poll_ccb) ? 1 : 0;
if ((ccb->acb != acb) || (ccb->startdone != ARCMSR_CCB_START)) {
@@ -3285,8 +3374,9 @@ static int arcmsr_hbaB_polling_ccbdone(struct AdapterControlBlock *acb,
uint32_t flag_ccb, poll_ccb_done = 0, poll_count = 0;
int index, rtn;
bool error;
- polling_hbb_ccb_retry:
+ unsigned long ccb_cdb_phy;
+polling_hbb_ccb_retry:
poll_count++;
/* clear doorbell interrupt */
writel(ARCMSR_DOORBELL_INT_CLEAR_PATTERN, reg->iop2drv_doorbell);
@@ -3312,7 +3402,10 @@ static int arcmsr_hbaB_polling_ccbdone(struct AdapterControlBlock *acb,
index %= ARCMSR_MAX_HBB_POSTQUEUE;
reg->doneq_index = index;
/* check if command done with no error*/
- arcmsr_cdb = (struct ARCMSR_CDB *)(acb->vir2phy_offset + (flag_ccb << 5));
+ ccb_cdb_phy = (flag_ccb << 5) & 0xffffffff;
+ if (acb->cdb_phyadd_hipart)
+ ccb_cdb_phy = ccb_cdb_phy | acb->cdb_phyadd_hipart;
+ arcmsr_cdb = (struct ARCMSR_CDB *)(acb->vir2phy_offset + ccb_cdb_phy);
ccb = container_of(arcmsr_cdb, struct CommandControlBlock, arcmsr_cdb);
poll_ccb_done |= (ccb == poll_ccb) ? 1 : 0;
if ((ccb->acb != acb) || (ccb->startdone != ARCMSR_CCB_START)) {
@@ -3345,12 +3438,14 @@ static int arcmsr_hbaC_polling_ccbdone(struct AdapterControlBlock *acb,
struct CommandControlBlock *poll_ccb)
{
struct MessageUnit_C __iomem *reg = acb->pmuC;
- uint32_t flag_ccb, ccb_cdb_phy;
+ uint32_t flag_ccb;
struct ARCMSR_CDB *arcmsr_cdb;
bool error;
struct CommandControlBlock *pCCB;
uint32_t poll_ccb_done = 0, poll_count = 0;
int rtn;
+ unsigned long ccb_cdb_phy;
+
polling_hbc_ccb_retry:
poll_count++;
while (1) {
@@ -3369,7 +3464,9 @@ polling_hbc_ccb_retry:
}
flag_ccb = readl(&reg->outbound_queueport_low);
ccb_cdb_phy = (flag_ccb & 0xFFFFFFF0);
- arcmsr_cdb = (struct ARCMSR_CDB *)(acb->vir2phy_offset + ccb_cdb_phy);/*frame must be 32 bytes aligned*/
+ if (acb->cdb_phyadd_hipart)
+ ccb_cdb_phy = ccb_cdb_phy | acb->cdb_phyadd_hipart;
+ arcmsr_cdb = (struct ARCMSR_CDB *)(acb->vir2phy_offset + ccb_cdb_phy);
pCCB = container_of(arcmsr_cdb, struct CommandControlBlock, arcmsr_cdb);
poll_ccb_done |= (pCCB == poll_ccb) ? 1 : 0;
/* check ifcommand done with no error*/
@@ -3403,9 +3500,9 @@ static int arcmsr_hbaD_polling_ccbdone(struct AdapterControlBlock *acb,
struct CommandControlBlock *poll_ccb)
{
bool error;
- uint32_t poll_ccb_done = 0, poll_count = 0, flag_ccb, ccb_cdb_phy;
+ uint32_t poll_ccb_done = 0, poll_count = 0, flag_ccb;
int rtn, doneq_index, index_stripped, outbound_write_pointer, toggle;
- unsigned long flags;
+ unsigned long flags, ccb_cdb_phy, cdb_phy_hipart;
struct ARCMSR_CDB *arcmsr_cdb;
struct CommandControlBlock *pCCB;
struct MessageUnit_D *pmu = acb->pmuD;
@@ -3437,8 +3534,12 @@ polling_hbaD_ccb_retry:
((toggle ^ 0x4000) + 1);
doneq_index = pmu->doneq_index;
spin_unlock_irqrestore(&acb->doneq_lock, flags);
+ cdb_phy_hipart = pmu->done_qbuffer[doneq_index &
+ 0xFFF].addressHigh;
flag_ccb = pmu->done_qbuffer[doneq_index & 0xFFF].addressLow;
ccb_cdb_phy = (flag_ccb & 0xFFFFFFF0);
+ if (acb->cdb_phyadd_hipart)
+ ccb_cdb_phy = ccb_cdb_phy | acb->cdb_phyadd_hipart;
arcmsr_cdb = (struct ARCMSR_CDB *)(acb->vir2phy_offset +
ccb_cdb_phy);
pCCB = container_of(arcmsr_cdb, struct CommandControlBlock,
@@ -3680,6 +3781,7 @@ static int arcmsr_iop_confirm(struct AdapterControlBlock *acb)
cdb_phyaddr = lower_32_bits(dma_coherent_handle);
cdb_phyaddr_hi32 = upper_32_bits(dma_coherent_handle);
acb->cdb_phyaddr_hi32 = cdb_phyaddr_hi32;
+ acb->cdb_phyadd_hipart = ((uint64_t)cdb_phyaddr_hi32) << 32;
/*
***********************************************************************
** if adapter type B, set window of "post command Q"
@@ -3744,7 +3846,6 @@ static int arcmsr_iop_confirm(struct AdapterControlBlock *acb)
}
break;
case ACB_ADAPTER_TYPE_C: {
- if (cdb_phyaddr_hi32 != 0) {
struct MessageUnit_C __iomem *reg = acb->pmuC;
printk(KERN_NOTICE "arcmsr%d: cdb_phyaddr_hi32=0x%x\n",
@@ -3759,7 +3860,6 @@ static int arcmsr_iop_confirm(struct AdapterControlBlock *acb)
return 1;
}
}
- }
break;
case ACB_ADAPTER_TYPE_D: {
uint32_t __iomem *rwbuffer;
@@ -3793,7 +3893,7 @@ static int arcmsr_iop_confirm(struct AdapterControlBlock *acb)
cdb_phyaddr_hi32 = (uint32_t)((dma_coherent_handle >> 16) >> 16);
writel(cdb_phyaddr, &reg->msgcode_rwbuffer[5]);
writel(cdb_phyaddr_hi32, &reg->msgcode_rwbuffer[6]);
- writel(acb->roundup_ccbsize, &reg->msgcode_rwbuffer[7]);
+ writel(acb->ioqueue_size, &reg->msgcode_rwbuffer[7]);
writel(ARCMSR_INBOUND_MESG0_SET_CONFIG, &reg->inbound_msgaddr0);
acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE;
writel(acb->out_doorbell, &reg->iobound_doorbell);
diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c
index 69c75426c5eb..c5fa5f3b00e9 100644
--- a/drivers/scsi/bnx2i/bnx2i_iscsi.c
+++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c
@@ -577,7 +577,7 @@ static void bnx2i_free_mp_bdt(struct bnx2i_hba *hba)
hba->dummy_buffer, hba->dummy_buf_dma);
hba->dummy_buffer = NULL;
}
- return;
+ return;
}
/**
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
index 194c294f9b6c..e7f1dd4f3b66 100644
--- a/drivers/scsi/gdth.c
+++ b/drivers/scsi/gdth.c
@@ -1,6 +1,6 @@
/************************************************************************
* Linux driver for *
- * ICP vortex GmbH: GDT ISA/EISA/PCI Disk Array Controllers *
+ * ICP vortex GmbH: GDT PCI Disk Array Controllers *
* Intel Corporation: Storage RAID Controllers *
* *
* gdth.c *
@@ -32,15 +32,10 @@
************************************************************************/
/* All GDT Disk Array Controllers are fully supported by this driver.
- * This includes the PCI/EISA/ISA SCSI Disk Array Controllers and the
+ * This includes the PCI SCSI Disk Array Controllers and the
* PCI Fibre Channel Disk Array Controllers. See gdth.h for a complete
* list of all controller types.
*
- * If you have one or more GDT3000/3020 EISA controllers with
- * controller BIOS disabled, you have to set the IRQ values with the
- * command line option "gdth=irq1,irq2,...", where the irq1,irq2,... are
- * the IRQ values for the EISA controllers.
- *
* After the optional list of IRQ values, other possible
* command line options are:
* disable:Y disable driver
@@ -61,14 +56,12 @@
* access a shared resource from several nodes,
* appropriate controller firmware required
* shared_access:N enable driver reserve/release protocol
- * probe_eisa_isa:Y scan for EISA/ISA controllers
- * probe_eisa_isa:N do not scan for EISA/ISA controllers
* force_dma32:Y use only 32 bit DMA mode
* force_dma32:N use 64 bit DMA mode, if supported
*
* The default values are: "gdth=disable:N,reserve_mode:1,reverse_scan:N,
* max_ids:127,rescan:N,hdr_channel:0,
- * shared_access:Y,probe_eisa_isa:N,force_dma32:N".
+ * shared_access:Y,force_dma32:N".
* Here is another example: "gdth=reserve_list:0,1,2,0,0,1,3,0,rescan:Y".
*
* When loading the gdth driver as a module, the same options are available.
@@ -79,7 +72,7 @@
*
* Default: "modprobe gdth disable=0 reserve_mode=1 reverse_scan=0
* max_ids=127 rescan=0 hdr_channel=0 shared_access=0
- * probe_eisa_isa=0 force_dma32=0"
+ * force_dma32=0"
* The other example: "modprobe gdth reserve_list=0,1,2,0,0,1,3,0 rescan=1".
*/
@@ -96,10 +89,6 @@
* phase: unused
*/
-
-/* interrupt coalescing */
-/* #define INT_COAL */
-
/* statistics */
#define GDTH_STATISTICS
@@ -122,10 +111,6 @@
#include <linux/list.h>
#include <linux/mutex.h>
#include <linux/slab.h>
-
-#ifdef GDTH_RTC
-#include <linux/mc146818rtc.h>
-#endif
#include <linux/reboot.h>
#include <asm/dma.h>
@@ -192,79 +177,9 @@ static void gdth_scsi_done(struct scsi_cmnd *scp);
#ifdef DEBUG_GDTH
static u8 DebugState = DEBUG_GDTH;
-
-#ifdef __SERIAL__
-#define MAX_SERBUF 160
-static void ser_init(void);
-static void ser_puts(char *str);
-static void ser_putc(char c);
-static int ser_printk(const char *fmt, ...);
-static char strbuf[MAX_SERBUF+1];
-#ifdef __COM2__
-#define COM_BASE 0x2f8
-#else
-#define COM_BASE 0x3f8
-#endif
-static void ser_init()
-{
- unsigned port=COM_BASE;
-
- outb(0x80,port+3);
- outb(0,port+1);
- /* 19200 Baud, if 9600: outb(12,port) */
- outb(6, port);
- outb(3,port+3);
- outb(0,port+1);
- /*
- ser_putc('I');
- ser_putc(' ');
- */
-}
-
-static void ser_puts(char *str)
-{
- char *ptr;
-
- ser_init();
- for (ptr=str;*ptr;++ptr)
- ser_putc(*ptr);
-}
-
-static void ser_putc(char c)
-{
- unsigned port=COM_BASE;
-
- while ((inb(port+5) & 0x20)==0);
- outb(c,port);
- if (c==0x0a)
- {
- while ((inb(port+5) & 0x20)==0);
- outb(0x0d,port);
- }
-}
-
-static int ser_printk(const char *fmt, ...)
-{
- va_list args;
- int i;
-
- va_start(args,fmt);
- i = vsprintf(strbuf,fmt,args);
- ser_puts(strbuf);
- va_end(args);
- return i;
-}
-
-#define TRACE(a) {if (DebugState==1) {ser_printk a;}}
-#define TRACE2(a) {if (DebugState==1 || DebugState==2) {ser_printk a;}}
-#define TRACE3(a) {if (DebugState!=0) {ser_printk a;}}
-
-#else /* !__SERIAL__ */
#define TRACE(a) {if (DebugState==1) {printk a;}}
#define TRACE2(a) {if (DebugState==1 || DebugState==2) {printk a;}}
#define TRACE3(a) {if (DebugState!=0) {printk a;}}
-#endif
-
#else /* !DEBUG */
#define TRACE(a)
#define TRACE2(a)
@@ -273,9 +188,6 @@ static int ser_printk(const char *fmt, ...)
#ifdef GDTH_STATISTICS
static u32 max_rq=0, max_index=0, max_sg=0;
-#ifdef INT_COAL
-static u32 max_int_coal=0;
-#endif
static u32 act_ints=0, act_ios=0, act_stats=0, act_rq=0;
static struct timer_list gdth_timer;
#endif
@@ -286,12 +198,6 @@ static struct timer_list gdth_timer;
#define BUS_L2P(a,b) ((b)>(a)->virt_bus ? (b-1):(b))
-#ifdef CONFIG_ISA
-static u8 gdth_drq_tab[4] = {5,6,7,7}; /* DRQ table */
-#endif
-#if defined(CONFIG_EISA) || defined(CONFIG_ISA)
-static u8 gdth_irq_tab[6] = {0,10,11,12,14,0}; /* IRQ table */
-#endif
static u8 gdth_polling; /* polling if TRUE */
static int gdth_ctr_count = 0; /* controller count */
static LIST_HEAD(gdth_instances); /* controller list */
@@ -325,10 +231,6 @@ static u8 gdth_direction_tab[0x100] = {
};
/* LILO and modprobe/insmod parameters */
-/* IRQ list for GDT3000/3020 EISA controllers */
-static int irq[MAXHA] __initdata =
-{0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
- 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
/* disable driver flag */
static int disable __initdata = 0;
/* reserve flag */
@@ -348,13 +250,10 @@ static int max_ids = MAXID;
static int rescan = 0;
/* shared access */
static int shared_access = 1;
-/* enable support for EISA and ISA controllers */
-static int probe_eisa_isa = 0;
/* 64 bit DMA mode, support for drives > 2 TB, if force_dma32 = 0 */
static int force_dma32 = 0;
/* parameters for modprobe/insmod */
-module_param_hw_array(irq, int, irq, NULL, 0);
module_param(disable, int, 0);
module_param(reserve_mode, int, 0);
module_param_array(reserve_list, int, NULL, 0);
@@ -363,7 +262,6 @@ module_param(hdr_channel, int, 0);
module_param(max_ids, int, 0);
module_param(rescan, int, 0);
module_param(shared_access, int, 0);
-module_param(probe_eisa_isa, int, 0);
module_param(force_dma32, int, 0);
MODULE_AUTHOR("Achim Leubner");
MODULE_LICENSE("GPL");
@@ -515,45 +413,6 @@ static void gdth_eval_mapping(u32 size, u32 *cyls, int *heads, int *secs)
}
}
-/* controller search and initialization functions */
-#ifdef CONFIG_EISA
-static int __init gdth_search_eisa(u16 eisa_adr)
-{
- u32 id;
-
- TRACE(("gdth_search_eisa() adr. %x\n",eisa_adr));
- id = inl(eisa_adr+ID0REG);
- if (id == GDT3A_ID || id == GDT3B_ID) { /* GDT3000A or GDT3000B */
- if ((inb(eisa_adr+EISAREG) & 8) == 0)
- return 0; /* not EISA configured */
- return 1;
- }
- if (id == GDT3_ID) /* GDT3000 */
- return 1;
-
- return 0;
-}
-#endif /* CONFIG_EISA */
-
-#ifdef CONFIG_ISA
-static int __init gdth_search_isa(u32 bios_adr)
-{
- void __iomem *addr;
- u32 id;
-
- TRACE(("gdth_search_isa() bios adr. %x\n",bios_adr));
- if ((addr = ioremap(bios_adr+BIOS_ID_OFFS, sizeof(u32))) != NULL) {
- id = readl(addr);
- iounmap(addr);
- if (id == GDT2_ID) /* GDT2000 */
- return 1;
- }
- return 0;
-}
-#endif /* CONFIG_ISA */
-
-#ifdef CONFIG_PCI
-
static bool gdth_search_vortex(u16 device)
{
if (device <= PCI_DEVICE_ID_VORTEX_GDT6555)
@@ -656,204 +515,7 @@ static int gdth_pci_init_one(struct pci_dev *pdev,
return 0;
}
-#endif /* CONFIG_PCI */
-#ifdef CONFIG_EISA
-static int __init gdth_init_eisa(u16 eisa_adr,gdth_ha_str *ha)
-{
- u32 retries,id;
- u8 prot_ver,eisacf,i,irq_found;
-
- TRACE(("gdth_init_eisa() adr. %x\n",eisa_adr));
-
- /* disable board interrupts, deinitialize services */
- outb(0xff,eisa_adr+EDOORREG);
- outb(0x00,eisa_adr+EDENABREG);
- outb(0x00,eisa_adr+EINTENABREG);
-
- outb(0xff,eisa_adr+LDOORREG);
- retries = INIT_RETRIES;
- gdth_delay(20);
- while (inb(eisa_adr+EDOORREG) != 0xff) {
- if (--retries == 0) {
- printk("GDT-EISA: Initialization error (DEINIT failed)\n");
- return 0;
- }
- gdth_delay(1);
- TRACE2(("wait for DEINIT: retries=%d\n",retries));
- }
- prot_ver = inb(eisa_adr+MAILBOXREG);
- outb(0xff,eisa_adr+EDOORREG);
- if (prot_ver != PROTOCOL_VERSION) {
- printk("GDT-EISA: Illegal protocol version\n");
- return 0;
- }
- ha->bmic = eisa_adr;
- ha->brd_phys = (u32)eisa_adr >> 12;
-
- outl(0,eisa_adr+MAILBOXREG);
- outl(0,eisa_adr+MAILBOXREG+4);
- outl(0,eisa_adr+MAILBOXREG+8);
- outl(0,eisa_adr+MAILBOXREG+12);
-
- /* detect IRQ */
- if ((id = inl(eisa_adr+ID0REG)) == GDT3_ID) {
- ha->oem_id = OEM_ID_ICP;
- ha->type = GDT_EISA;
- ha->stype = id;
- outl(1,eisa_adr+MAILBOXREG+8);
- outb(0xfe,eisa_adr+LDOORREG);
- retries = INIT_RETRIES;
- gdth_delay(20);
- while (inb(eisa_adr+EDOORREG) != 0xfe) {
- if (--retries == 0) {
- printk("GDT-EISA: Initialization error (get IRQ failed)\n");
- return 0;
- }
- gdth_delay(1);
- }
- ha->irq = inb(eisa_adr+MAILBOXREG);
- outb(0xff,eisa_adr+EDOORREG);
- TRACE2(("GDT3000/3020: IRQ=%d\n",ha->irq));
- /* check the result */
- if (ha->irq == 0) {
- TRACE2(("Unknown IRQ, use IRQ table from cmd line !\n"));
- for (i = 0, irq_found = FALSE;
- i < MAXHA && irq[i] != 0xff; ++i) {
- if (irq[i]==10 || irq[i]==11 || irq[i]==12 || irq[i]==14) {
- irq_found = TRUE;
- break;
- }
- }
- if (irq_found) {
- ha->irq = irq[i];
- irq[i] = 0;
- printk("GDT-EISA: Can not detect controller IRQ,\n");
- printk("Use IRQ setting from command line (IRQ = %d)\n",
- ha->irq);
- } else {
- printk("GDT-EISA: Initialization error (unknown IRQ), Enable\n");
- printk("the controller BIOS or use command line parameters\n");
- return 0;
- }
- }
- } else {
- eisacf = inb(eisa_adr+EISAREG) & 7;
- if (eisacf > 4) /* level triggered */
- eisacf -= 4;
- ha->irq = gdth_irq_tab[eisacf];
- ha->oem_id = OEM_ID_ICP;
- ha->type = GDT_EISA;
- ha->stype = id;
- }
-
- ha->dma64_support = 0;
- return 1;
-}
-#endif /* CONFIG_EISA */
-
-#ifdef CONFIG_ISA
-static int __init gdth_init_isa(u32 bios_adr,gdth_ha_str *ha)
-{
- register gdt2_dpram_str __iomem *dp2_ptr;
- int i;
- u8 irq_drq,prot_ver;
- u32 retries;
-
- TRACE(("gdth_init_isa() bios adr. %x\n",bios_adr));
-
- ha->brd = ioremap(bios_adr, sizeof(gdt2_dpram_str));
- if (ha->brd == NULL) {
- printk("GDT-ISA: Initialization error (DPMEM remap error)\n");
- return 0;
- }
- dp2_ptr = ha->brd;
- writeb(1, &dp2_ptr->io.memlock); /* switch off write protection */
- /* reset interface area */
- memset_io(&dp2_ptr->u, 0, sizeof(dp2_ptr->u));
- if (readl(&dp2_ptr->u) != 0) {
- printk("GDT-ISA: Initialization error (DPMEM write error)\n");
- iounmap(ha->brd);
- return 0;
- }
-
- /* disable board interrupts, read DRQ and IRQ */
- writeb(0xff, &dp2_ptr->io.irqdel);
- writeb(0x00, &dp2_ptr->io.irqen);
- writeb(0x00, &dp2_ptr->u.ic.S_Status);
- writeb(0x00, &dp2_ptr->u.ic.Cmd_Index);
-
- irq_drq = readb(&dp2_ptr->io.rq);
- for (i=0; i<3; ++i) {
- if ((irq_drq & 1)==0)
- break;
- irq_drq >>= 1;
- }
- ha->drq = gdth_drq_tab[i];
-
- irq_drq = readb(&dp2_ptr->io.rq) >> 3;
- for (i=1; i<5; ++i) {
- if ((irq_drq & 1)==0)
- break;
- irq_drq >>= 1;
- }
- ha->irq = gdth_irq_tab[i];
-
- /* deinitialize services */
- writel(bios_adr, &dp2_ptr->u.ic.S_Info[0]);
- writeb(0xff, &dp2_ptr->u.ic.S_Cmd_Indx);
- writeb(0, &dp2_ptr->io.event);
- retries = INIT_RETRIES;
- gdth_delay(20);
- while (readb(&dp2_ptr->u.ic.S_Status) != 0xff) {
- if (--retries == 0) {
- printk("GDT-ISA: Initialization error (DEINIT failed)\n");
- iounmap(ha->brd);
- return 0;
- }
- gdth_delay(1);
- }
- prot_ver = (u8)readl(&dp2_ptr->u.ic.S_Info[0]);
- writeb(0, &dp2_ptr->u.ic.Status);
- writeb(0xff, &dp2_ptr->io.irqdel);
- if (prot_ver != PROTOCOL_VERSION) {
- printk("GDT-ISA: Illegal protocol version\n");
- iounmap(ha->brd);
- return 0;
- }
-
- ha->oem_id = OEM_ID_ICP;
- ha->type = GDT_ISA;
- ha->ic_all_size = sizeof(dp2_ptr->u);
- ha->stype= GDT2_ID;
- ha->brd_phys = bios_adr >> 4;
-
- /* special request to controller BIOS */
- writel(0x00, &dp2_ptr->u.ic.S_Info[0]);
- writel(0x00, &dp2_ptr->u.ic.S_Info[1]);
- writel(0x01, &dp2_ptr->u.ic.S_Info[2]);
- writel(0x00, &dp2_ptr->u.ic.S_Info[3]);
- writeb(0xfe, &dp2_ptr->u.ic.S_Cmd_Indx);
- writeb(0, &dp2_ptr->io.event);
- retries = INIT_RETRIES;
- gdth_delay(20);
- while (readb(&dp2_ptr->u.ic.S_Status) != 0xfe) {
- if (--retries == 0) {
- printk("GDT-ISA: Initialization error\n");
- iounmap(ha->brd);
- return 0;
- }
- gdth_delay(1);
- }
- writeb(0, &dp2_ptr->u.ic.Status);
- writeb(0xff, &dp2_ptr->io.irqdel);
-
- ha->dma64_support = 0;
- return 1;
-}
-#endif /* CONFIG_ISA */
-
-#ifdef CONFIG_PCI
static int gdth_init_pci(struct pci_dev *pdev, gdth_pci_str *pcistr,
gdth_ha_str *ha)
{
@@ -1228,30 +890,19 @@ static int gdth_init_pci(struct pci_dev *pdev, gdth_pci_str *pcistr,
return 1;
}
-#endif /* CONFIG_PCI */
/* controller protocol functions */
static void gdth_enable_int(gdth_ha_str *ha)
{
unsigned long flags;
- gdt2_dpram_str __iomem *dp2_ptr;
gdt6_dpram_str __iomem *dp6_ptr;
gdt6m_dpram_str __iomem *dp6m_ptr;
TRACE(("gdth_enable_int() hanum %d\n",ha->hanum));
spin_lock_irqsave(&ha->smp_lock, flags);
- if (ha->type == GDT_EISA) {
- outb(0xff, ha->bmic + EDOORREG);
- outb(0xff, ha->bmic + EDENABREG);
- outb(0x01, ha->bmic + EINTENABREG);
- } else if (ha->type == GDT_ISA) {
- dp2_ptr = ha->brd;
- writeb(1, &dp2_ptr->io.irqdel);
- writeb(0, &dp2_ptr->u.ic.Cmd_Index);
- writeb(1, &dp2_ptr->io.irqen);
- } else if (ha->type == GDT_PCI) {
+ if (ha->type == GDT_PCI) {
dp6_ptr = ha->brd;
writeb(1, &dp6_ptr->io.irqdel);
writeb(0, &dp6_ptr->u.ic.Cmd_Index);
@@ -1275,12 +926,7 @@ static u8 gdth_get_status(gdth_ha_str *ha)
TRACE(("gdth_get_status() irq %d ctr_count %d\n", ha->irq, gdth_ctr_count));
- if (ha->type == GDT_EISA)
- IStatus = inb((u16)ha->bmic + EDOORREG);
- else if (ha->type == GDT_ISA)
- IStatus =
- readb(&((gdt2_dpram_str __iomem *)ha->brd)->u.ic.Cmd_Index);
- else if (ha->type == GDT_PCI)
+ if (ha->type == GDT_PCI)
IStatus =
readb(&((gdt6_dpram_str __iomem *)ha->brd)->u.ic.Cmd_Index);
else if (ha->type == GDT_PCINEW)
@@ -1298,11 +944,7 @@ static int gdth_test_busy(gdth_ha_str *ha)
TRACE(("gdth_test_busy() hanum %d\n", ha->hanum));
- if (ha->type == GDT_EISA)
- gdtsema0 = (int)inb(ha->bmic + SEMA0REG);
- else if (ha->type == GDT_ISA)
- gdtsema0 = (int)readb(&((gdt2_dpram_str __iomem *)ha->brd)->u.ic.Sema0);
- else if (ha->type == GDT_PCI)
+ if (ha->type == GDT_PCI)
gdtsema0 = (int)readb(&((gdt6_dpram_str __iomem *)ha->brd)->u.ic.Sema0);
else if (ha->type == GDT_PCINEW)
gdtsema0 = (int)inb(PTR2USHORT(&ha->plx->sema0_reg));
@@ -1336,11 +978,7 @@ static void gdth_set_sema0(gdth_ha_str *ha)
{
TRACE(("gdth_set_sema0() hanum %d\n", ha->hanum));
- if (ha->type == GDT_EISA) {
- outb(1, ha->bmic + SEMA0REG);
- } else if (ha->type == GDT_ISA) {
- writeb(1, &((gdt2_dpram_str __iomem *)ha->brd)->u.ic.Sema0);
- } else if (ha->type == GDT_PCI) {
+ if (ha->type == GDT_PCI) {
writeb(1, &((gdt6_dpram_str __iomem *)ha->brd)->u.ic.Sema0);
} else if (ha->type == GDT_PCINEW) {
outb(1, PTR2USHORT(&ha->plx->sema0_reg));
@@ -1356,7 +994,6 @@ static void gdth_copy_command(gdth_ha_str *ha)
register gdt6m_dpram_str __iomem *dp6m_ptr;
register gdt6c_dpram_str __iomem *dp6c_ptr;
gdt6_dpram_str __iomem *dp6_ptr;
- gdt2_dpram_str __iomem *dp2_ptr;
u16 cp_count,dp_offset,cmd_no;
TRACE(("gdth_copy_command() hanum %d\n", ha->hanum));
@@ -1367,8 +1004,6 @@ static void gdth_copy_command(gdth_ha_str *ha)
cmd_ptr = ha->pccb;
++ha->cmd_cnt;
- if (ha->type == GDT_EISA)
- return; /* no DPMEM, no copy */
/* set cpcount dword aligned */
if (cp_count & 3)
@@ -1377,14 +1012,7 @@ static void gdth_copy_command(gdth_ha_str *ha)
ha->cmd_offs_dpmem += cp_count;
/* set offset and service, copy command to DPMEM */
- if (ha->type == GDT_ISA) {
- dp2_ptr = ha->brd;
- writew(dp_offset + DPMEM_COMMAND_OFFSET,
- &dp2_ptr->u.ic.comm_queue[cmd_no].offset);
- writew((u16)cmd_ptr->Service,
- &dp2_ptr->u.ic.comm_queue[cmd_no].serv_id);
- memcpy_toio(&dp2_ptr->u.ic.gdt_dpr_cmd[dp_offset],cmd_ptr,cp_count);
- } else if (ha->type == GDT_PCI) {
+ if (ha->type == GDT_PCI) {
dp6_ptr = ha->brd;
writew(dp_offset + DPMEM_COMMAND_OFFSET,
&dp6_ptr->u.ic.comm_queue[cmd_no].offset);
@@ -1430,13 +1058,7 @@ static void gdth_release_event(gdth_ha_str *ha)
if (ha->pccb->OpCode == GDT_INIT)
ha->pccb->Service |= 0x80;
- if (ha->type == GDT_EISA) {
- if (ha->pccb->OpCode == GDT_INIT) /* store DMA buffer */
- outl(ha->ccb_phys, ha->bmic + MAILBOXREG);
- outb(ha->pccb->Service, ha->bmic + LDOORREG);
- } else if (ha->type == GDT_ISA) {
- writeb(0, &((gdt2_dpram_str __iomem *)ha->brd)->io.event);
- } else if (ha->type == GDT_PCI) {
+ if (ha->type == GDT_PCI) {
writeb(0, &((gdt6_dpram_str __iomem *)ha->brd)->io.event);
} else if (ha->type == GDT_PCINEW) {
outb(1, PTR2USHORT(&ha->plx->ldoor_reg));
@@ -1560,15 +1182,7 @@ static int gdth_search_drives(gdth_ha_str *ha)
gdth_arcdl_str *alst;
gdth_alist_str *alst2;
gdth_oem_str_ioctl *oemstr;
-#ifdef INT_COAL
- gdth_perf_modes *pmod;
-#endif
-#ifdef GDTH_RTC
- u8 rtc[12];
- unsigned long flags;
-#endif
-
TRACE(("gdth_search_drives() hanum %d\n", ha->hanum));
ok = 0;
@@ -1588,29 +1202,6 @@ static int gdth_search_drives(gdth_ha_str *ha)
}
TRACE2(("gdth_search_drives(): SCREENSERVICE initialized\n"));
-#ifdef GDTH_RTC
- /* read realtime clock info, send to controller */
- /* 1. wait for the falling edge of update flag */
- spin_lock_irqsave(&rtc_lock, flags);
- for (j = 0; j < 1000000; ++j)
- if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)
- break;
- for (j = 0; j < 1000000; ++j)
- if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
- break;
- /* 2. read info */
- do {
- for (j = 0; j < 12; ++j)
- rtc[j] = CMOS_READ(j);
- } while (rtc[0] != CMOS_READ(0));
- spin_unlock_irqrestore(&rtc_lock, flags);
- TRACE2(("gdth_search_drives(): RTC: %x/%x/%x\n",*(u32 *)&rtc[0],
- *(u32 *)&rtc[4], *(u32 *)&rtc[8]));
- /* 3. send to controller firmware */
- gdth_internal_cmd(ha, SCREENSERVICE, GDT_REALTIME, *(u32 *)&rtc[0],
- *(u32 *)&rtc[4], *(u32 *)&rtc[8]);
-#endif
-
/* unfreeze all IOs */
gdth_internal_cmd(ha, CACHESERVICE, GDT_UNFREEZE_IO, 0, 0, 0);
@@ -1633,35 +1224,6 @@ static int gdth_search_drives(gdth_ha_str *ha)
cdev_cnt = (u16)ha->info;
ha->fw_vers = ha->service;
-#ifdef INT_COAL
- if (ha->type == GDT_PCIMPR) {
- /* set perf. modes */
- pmod = (gdth_perf_modes *)ha->pscratch;
- pmod->version = 1;
- pmod->st_mode = 1; /* enable one status buffer */
- *((u64 *)&pmod->st_buff_addr1) = ha->coal_stat_phys;
- pmod->st_buff_indx1 = COALINDEX;
- pmod->st_buff_addr2 = 0;
- pmod->st_buff_u_addr2 = 0;
- pmod->st_buff_indx2 = 0;
- pmod->st_buff_size = sizeof(gdth_coal_status) * MAXOFFSETS;
- pmod->cmd_mode = 0; // disable all cmd buffers
- pmod->cmd_buff_addr1 = 0;
- pmod->cmd_buff_u_addr1 = 0;
- pmod->cmd_buff_indx1 = 0;
- pmod->cmd_buff_addr2 = 0;
- pmod->cmd_buff_u_addr2 = 0;
- pmod->cmd_buff_indx2 = 0;
- pmod->cmd_buff_size = 0;
- pmod->reserved1 = 0;
- pmod->reserved2 = 0;
- if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, SET_PERF_MODES,
- INVALID_CHANNEL,sizeof(gdth_perf_modes))) {
- printk("GDT-HA %d: Interrupt coalescing activated\n", ha->hanum);
- }
- }
-#endif
-
/* detect number of buses - try new IOCTL */
iocr = (gdth_raw_iochan_str *)ha->pscratch;
iocr->hdr.version = 0xffffffff;
@@ -2433,9 +1995,6 @@ static int gdth_fill_cache_cmd(gdth_ha_str *ha, struct scsi_cmnd *scp,
TRACE(("gdth_fill_cache_cmd() cmd 0x%x cmdsize %d hdrive %d\n",
scp->cmnd[0],scp->cmd_len,hdrive));
- if (ha->type==GDT_EISA && ha->cmd_cnt>0)
- return 0;
-
mode64 = (ha->cache_feat & GDT_64BIT) ? TRUE : FALSE;
/* test for READ_16, WRITE_16 if !mode64 ? ---
not required, should not occur due to error return on
@@ -2518,9 +2077,9 @@ static int gdth_fill_cache_cmd(gdth_ha_str *ha, struct scsi_cmnd *scp,
if (scsi_bufflen(scp)) {
cmndinfo->dma_dir = (read_write == 1 ?
- PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);
- sgcnt = pci_map_sg(ha->pdev, scsi_sglist(scp), scsi_sg_count(scp),
- cmndinfo->dma_dir);
+ DMA_TO_DEVICE : DMA_FROM_DEVICE);
+ sgcnt = dma_map_sg(&ha->pdev->dev, scsi_sglist(scp),
+ scsi_sg_count(scp), cmndinfo->dma_dir);
if (mode64) {
struct scatterlist *sl;
@@ -2528,12 +2087,6 @@ static int gdth_fill_cache_cmd(gdth_ha_str *ha, struct scsi_cmnd *scp,
cmdp->u.cache64.sg_canz = sgcnt;
scsi_for_each_sg(scp, sl, sgcnt, i) {
cmdp->u.cache64.sg_lst[i].sg_ptr = sg_dma_address(sl);
-#ifdef GDTH_DMA_STATISTICS
- if (cmdp->u.cache64.sg_lst[i].sg_ptr > (u64)0xffffffff)
- ha->dma64_cnt++;
- else
- ha->dma32_cnt++;
-#endif
cmdp->u.cache64.sg_lst[i].sg_len = sg_dma_len(sl);
}
} else {
@@ -2543,9 +2096,6 @@ static int gdth_fill_cache_cmd(gdth_ha_str *ha, struct scsi_cmnd *scp,
cmdp->u.cache.sg_canz = sgcnt;
scsi_for_each_sg(scp, sl, sgcnt, i) {
cmdp->u.cache.sg_lst[i].sg_ptr = sg_dma_address(sl);
-#ifdef GDTH_DMA_STATISTICS
- ha->dma32_cnt++;
-#endif
cmdp->u.cache.sg_lst[i].sg_len = sg_dma_len(sl);
}
}
@@ -2603,8 +2153,6 @@ static int gdth_fill_raw_cmd(gdth_ha_str *ha, struct scsi_cmnd *scp, u8 b)
dma_addr_t sense_paddr;
int cmd_index, sgcnt, mode64;
u8 t,l;
- struct page *page;
- unsigned long offset;
struct gdth_cmndinfo *cmndinfo;
t = scp->device->id;
@@ -2613,9 +2161,6 @@ static int gdth_fill_raw_cmd(gdth_ha_str *ha, struct scsi_cmnd *scp, u8 b)
TRACE(("gdth_fill_raw_cmd() cmd 0x%x bus %d ID %d LUN %d\n",
scp->cmnd[0],b,t,l));
- if (ha->type==GDT_EISA && ha->cmd_cnt>0)
- return 0;
-
mode64 = (ha->raw_feat & GDT_64BIT) ? TRUE : FALSE;
cmdp->Service = SCSIRAWSERVICE;
@@ -2649,10 +2194,8 @@ static int gdth_fill_raw_cmd(gdth_ha_str *ha, struct scsi_cmnd *scp, u8 b)
}
} else {
- page = virt_to_page(scp->sense_buffer);
- offset = (unsigned long)scp->sense_buffer & ~PAGE_MASK;
- sense_paddr = pci_map_page(ha->pdev,page,offset,
- 16,PCI_DMA_FROMDEVICE);
+ sense_paddr = dma_map_single(&ha->pdev->dev, scp->sense_buffer, 16,
+ DMA_FROM_DEVICE);
cmndinfo->sense_paddr = sense_paddr;
cmdp->OpCode = GDT_WRITE; /* always */
@@ -2693,9 +2236,9 @@ static int gdth_fill_raw_cmd(gdth_ha_str *ha, struct scsi_cmnd *scp, u8 b)
}
if (scsi_bufflen(scp)) {
- cmndinfo->dma_dir = PCI_DMA_BIDIRECTIONAL;
- sgcnt = pci_map_sg(ha->pdev, scsi_sglist(scp), scsi_sg_count(scp),
- cmndinfo->dma_dir);
+ cmndinfo->dma_dir = DMA_BIDIRECTIONAL;
+ sgcnt = dma_map_sg(&ha->pdev->dev, scsi_sglist(scp),
+ scsi_sg_count(scp), cmndinfo->dma_dir);
if (mode64) {
struct scatterlist *sl;
@@ -2703,12 +2246,6 @@ static int gdth_fill_raw_cmd(gdth_ha_str *ha, struct scsi_cmnd *scp, u8 b)
cmdp->u.raw64.sg_ranz = sgcnt;
scsi_for_each_sg(scp, sl, sgcnt, i) {
cmdp->u.raw64.sg_lst[i].sg_ptr = sg_dma_address(sl);
-#ifdef GDTH_DMA_STATISTICS
- if (cmdp->u.raw64.sg_lst[i].sg_ptr > (u64)0xffffffff)
- ha->dma64_cnt++;
- else
- ha->dma32_cnt++;
-#endif
cmdp->u.raw64.sg_lst[i].sg_len = sg_dma_len(sl);
}
} else {
@@ -2718,9 +2255,6 @@ static int gdth_fill_raw_cmd(gdth_ha_str *ha, struct scsi_cmnd *scp, u8 b)
cmdp->u.raw.sg_ranz = sgcnt;
scsi_for_each_sg(scp, sl, sgcnt, i) {
cmdp->u.raw.sg_lst[i].sg_ptr = sg_dma_address(sl);
-#ifdef GDTH_DMA_STATISTICS
- ha->dma32_cnt++;
-#endif
cmdp->u.raw.sg_lst[i].sg_len = sg_dma_len(sl);
}
}
@@ -2778,9 +2312,6 @@ static int gdth_special_cmd(gdth_ha_str *ha, struct scsi_cmnd *scp)
cmdp= ha->pccb;
TRACE2(("gdth_special_cmd(): "));
- if (ha->type==GDT_EISA && ha->cmd_cnt>0)
- return 0;
-
*cmdp = *cmndinfo->internal_cmd_str;
cmdp->RequestBuffer = scp;
@@ -2959,18 +2490,11 @@ static irqreturn_t __gdth_interrupt(gdth_ha_str *ha,
{
gdt6m_dpram_str __iomem *dp6m_ptr = NULL;
gdt6_dpram_str __iomem *dp6_ptr;
- gdt2_dpram_str __iomem *dp2_ptr;
struct scsi_cmnd *scp;
int rval, i;
u8 IStatus;
u16 Service;
unsigned long flags = 0;
-#ifdef INT_COAL
- int coalesced = FALSE;
- int next = FALSE;
- gdth_coal_status *pcs = NULL;
- int act_int_coal = 0;
-#endif
TRACE(("gdth_interrupt() IRQ %d\n", ha->irq));
@@ -2997,53 +2521,7 @@ static irqreturn_t __gdth_interrupt(gdth_ha_str *ha,
++act_ints;
#endif
-#ifdef INT_COAL
- /* See if the fw is returning coalesced status */
- if (IStatus == COALINDEX) {
- /* Coalesced status. Setup the initial status
- buffer pointer and flags */
- pcs = ha->coal_stat;
- coalesced = TRUE;
- next = TRUE;
- }
-
- do {
- if (coalesced) {
- /* For coalesced requests all status
- information is found in the status buffer */
- IStatus = (u8)(pcs->status & 0xff);
- }
-#endif
-
- if (ha->type == GDT_EISA) {
- if (IStatus & 0x80) { /* error flag */
- IStatus &= ~0x80;
- ha->status = inw(ha->bmic + MAILBOXREG+8);
- TRACE2(("gdth_interrupt() error %d/%d\n",IStatus,ha->status));
- } else /* no error */
- ha->status = S_OK;
- ha->info = inl(ha->bmic + MAILBOXREG+12);
- ha->service = inw(ha->bmic + MAILBOXREG+10);
- ha->info2 = inl(ha->bmic + MAILBOXREG+4);
-
- outb(0xff, ha->bmic + EDOORREG); /* acknowledge interrupt */
- outb(0x00, ha->bmic + SEMA1REG); /* reset status semaphore */
- } else if (ha->type == GDT_ISA) {
- dp2_ptr = ha->brd;
- if (IStatus & 0x80) { /* error flag */
- IStatus &= ~0x80;
- ha->status = readw(&dp2_ptr->u.ic.Status);
- TRACE2(("gdth_interrupt() error %d/%d\n",IStatus,ha->status));
- } else /* no error */
- ha->status = S_OK;
- ha->info = readl(&dp2_ptr->u.ic.Info[0]);
- ha->service = readw(&dp2_ptr->u.ic.Service);
- ha->info2 = readl(&dp2_ptr->u.ic.Info[1]);
-
- writeb(0xff, &dp2_ptr->io.irqdel); /* acknowledge interrupt */
- writeb(0, &dp2_ptr->u.ic.Cmd_Index);/* reset command index */
- writeb(0, &dp2_ptr->io.Sema1); /* reset status semaphore */
- } else if (ha->type == GDT_PCI) {
+ if (ha->type == GDT_PCI) {
dp6_ptr = ha->brd;
if (IStatus & 0x80) { /* error flag */
IStatus &= ~0x80;
@@ -3075,28 +2553,15 @@ static irqreturn_t __gdth_interrupt(gdth_ha_str *ha,
dp6m_ptr = ha->brd;
if (IStatus & 0x80) { /* error flag */
IStatus &= ~0x80;
-#ifdef INT_COAL
- if (coalesced)
- ha->status = pcs->ext_status & 0xffff;
- else
-#endif
- ha->status = readw(&dp6m_ptr->i960r.status);
+ ha->status = readw(&dp6m_ptr->i960r.status);
TRACE2(("gdth_interrupt() error %d/%d\n",IStatus,ha->status));
} else /* no error */
ha->status = S_OK;
-#ifdef INT_COAL
- /* get information */
- if (coalesced) {
- ha->info = pcs->info0;
- ha->info2 = pcs->info1;
- ha->service = (pcs->ext_status >> 16) & 0xffff;
- } else
-#endif
- {
- ha->info = readl(&dp6m_ptr->i960r.info[0]);
- ha->service = readw(&dp6m_ptr->i960r.service);
- ha->info2 = readl(&dp6m_ptr->i960r.info[1]);
- }
+
+ ha->info = readl(&dp6m_ptr->i960r.info[0]);
+ ha->service = readw(&dp6m_ptr->i960r.service);
+ ha->info2 = readl(&dp6m_ptr->i960r.info[1]);
+
/* event string */
if (IStatus == ASYNCINDEX) {
if (ha->service != SCREENSERVICE &&
@@ -3111,15 +2576,8 @@ static irqreturn_t __gdth_interrupt(gdth_ha_str *ha,
}
}
}
-#ifdef INT_COAL
- /* Make sure that non coalesced interrupts get cleared
- before being handled by gdth_async_event/gdth_sync_event */
- if (!coalesced)
-#endif
- {
- writeb(0xff, &dp6m_ptr->i960r.edoor_reg);
- writeb(0, &dp6m_ptr->i960r.sema1_reg);
- }
+ writeb(0xff, &dp6m_ptr->i960r.edoor_reg);
+ writeb(0, &dp6m_ptr->i960r.sema1_reg);
} else {
TRACE2(("gdth_interrupt() unknown controller type\n"));
if (!gdth_polling)
@@ -3182,31 +2640,6 @@ static irqreturn_t __gdth_interrupt(gdth_ha_str *ha,
gdth_scsi_done(scp);
}
-#ifdef INT_COAL
- if (coalesced) {
- /* go to the next status in the status buffer */
- ++pcs;
-#ifdef GDTH_STATISTICS
- ++act_int_coal;
- if (act_int_coal > max_int_coal) {
- max_int_coal = act_int_coal;
- printk("GDT: max_int_coal = %d\n",(u16)max_int_coal);
- }
-#endif
- /* see if there is another status */
- if (pcs->status == 0)
- /* Stop the coalesce loop */
- next = FALSE;
- }
- } while (next);
-
- /* coalescing only for new GDT_PCIMPR controllers available */
- if (ha->type == GDT_PCIMPR && coalesced) {
- writeb(0xff, &dp6m_ptr->i960r.edoor_reg);
- writeb(0, &dp6m_ptr->i960r.sema1_reg);
- }
-#endif
-
gdth_next(ha);
return IRQ_HANDLED;
}
@@ -3313,12 +2746,12 @@ static int gdth_sync_event(gdth_ha_str *ha, int service, u8 index,
return 2;
}
if (scsi_bufflen(scp))
- pci_unmap_sg(ha->pdev, scsi_sglist(scp), scsi_sg_count(scp),
+ dma_unmap_sg(&ha->pdev->dev, scsi_sglist(scp), scsi_sg_count(scp),
cmndinfo->dma_dir);
if (cmndinfo->sense_paddr)
- pci_unmap_page(ha->pdev, cmndinfo->sense_paddr, 16,
- PCI_DMA_FROMDEVICE);
+ dma_unmap_page(&ha->pdev->dev, cmndinfo->sense_paddr, 16,
+ DMA_FROM_DEVICE);
if (ha->status == S_OK) {
cmndinfo->status = S_OK;
@@ -3610,12 +3043,7 @@ static int gdth_async_event(gdth_ha_str *ha)
+ sizeof(u64);
ha->cmd_cnt = 0;
gdth_copy_command(ha);
- if (ha->type == GDT_EISA)
- printk("[EISA slot %d] ",(u16)ha->brd_phys);
- else if (ha->type == GDT_ISA)
- printk("[DPMEM 0x%4X] ",(u16)ha->brd_phys);
- else
- printk("[PCI %d/%d] ",(u16)(ha->brd_phys>>8),
+ printk("[PCI %d/%d] ",(u16)(ha->brd_phys>>8),
(u16)((ha->brd_phys>>3)&0x1f));
gdth_release_event(ha);
}
@@ -3756,23 +3184,12 @@ static inline void gdth_timer_init(void)
static void __init internal_setup(char *str,int *ints)
{
- int i, argc;
+ int i;
char *cur_str, *argv;
TRACE2(("internal_setup() str %s ints[0] %d\n",
str ? str:"NULL", ints ? ints[0]:0));
- /* read irq[] from ints[] */
- if (ints) {
- argc = ints[0];
- if (argc > 0) {
- if (argc > MAXHA)
- argc = MAXHA;
- for (i = 0; i < argc; ++i)
- irq[i] = ints[i+1];
- }
- }
-
/* analyse string */
argv = str;
while (argv && (cur_str = strchr(argv, ':'))) {
@@ -3799,8 +3216,6 @@ static void __init internal_setup(char *str,int *ints)
rescan = val;
else if (!strncmp(argv, "shared_access:", 14))
shared_access = val;
- else if (!strncmp(argv, "probe_eisa_isa:", 15))
- probe_eisa_isa = val;
else if (!strncmp(argv, "reserve_list:", 13)) {
reserve_list[0] = val;
for (i = 1; i < MAX_RES_ARGS; i++) {
@@ -3847,18 +3262,7 @@ static const char *gdth_ctr_name(gdth_ha_str *ha)
{
TRACE2(("gdth_ctr_name()\n"));
- if (ha->type == GDT_EISA) {
- switch (ha->stype) {
- case GDT3_ID:
- return("GDT3000/3020");
- case GDT3A_ID:
- return("GDT3000A/3020A/3050A");
- case GDT3B_ID:
- return("GDT3000B/3010A");
- }
- } else if (ha->type == GDT_ISA) {
- return("GDT2000/2020");
- } else if (ha->type == GDT_PCI) {
+ if (ha->type == GDT_PCI) {
switch (ha->pdev->device) {
case PCI_DEVICE_ID_VORTEX_GDT60x0:
return("GDT6000/6020/6050");
@@ -4155,131 +3559,147 @@ static int ioc_resetdrv(void __user *arg, char *cmnd)
return 0;
}
-static int ioc_general(void __user *arg, char *cmnd)
+static void gdth_ioc_cacheservice(gdth_ha_str *ha, gdth_ioctl_general *gen,
+ u64 paddr)
{
- gdth_ioctl_general gen;
- char *buf = NULL;
- u64 paddr;
- gdth_ha_str *ha;
- int rval;
-
- if (copy_from_user(&gen, arg, sizeof(gdth_ioctl_general)))
- return -EFAULT;
- ha = gdth_find_ha(gen.ionode);
- if (!ha)
- return -EFAULT;
-
- if (gen.data_len > INT_MAX)
- return -EINVAL;
- if (gen.sense_len > INT_MAX)
- return -EINVAL;
- if (gen.data_len + gen.sense_len > INT_MAX)
- return -EINVAL;
-
- if (gen.data_len + gen.sense_len != 0) {
- if (!(buf = gdth_ioctl_alloc(ha, gen.data_len + gen.sense_len,
- FALSE, &paddr)))
- return -EFAULT;
- if (copy_from_user(buf, arg + sizeof(gdth_ioctl_general),
- gen.data_len + gen.sense_len)) {
- gdth_ioctl_free(ha, gen.data_len+gen.sense_len, buf, paddr);
- return -EFAULT;
- }
+ if (ha->cache_feat & GDT_64BIT) {
+ /* copy elements from 32-bit IOCTL structure */
+ gen->command.u.cache64.BlockCnt = gen->command.u.cache.BlockCnt;
+ gen->command.u.cache64.BlockNo = gen->command.u.cache.BlockNo;
+ gen->command.u.cache64.DeviceNo = gen->command.u.cache.DeviceNo;
+
+ if (ha->cache_feat & SCATTER_GATHER) {
+ gen->command.u.cache64.DestAddr = (u64)-1;
+ gen->command.u.cache64.sg_canz = 1;
+ gen->command.u.cache64.sg_lst[0].sg_ptr = paddr;
+ gen->command.u.cache64.sg_lst[0].sg_len = gen->data_len;
+ gen->command.u.cache64.sg_lst[1].sg_len = 0;
+ } else {
+ gen->command.u.cache64.DestAddr = paddr;
+ gen->command.u.cache64.sg_canz = 0;
+ }
+ } else {
+ if (ha->cache_feat & SCATTER_GATHER) {
+ gen->command.u.cache.DestAddr = 0xffffffff;
+ gen->command.u.cache.sg_canz = 1;
+ gen->command.u.cache.sg_lst[0].sg_ptr = (u32)paddr;
+ gen->command.u.cache.sg_lst[0].sg_len = gen->data_len;
+ gen->command.u.cache.sg_lst[1].sg_len = 0;
+ } else {
+ gen->command.u.cache.DestAddr = paddr;
+ gen->command.u.cache.sg_canz = 0;
+ }
+ }
+}
- if (gen.command.OpCode == GDT_IOCTL) {
- gen.command.u.ioctl.p_param = paddr;
- } else if (gen.command.Service == CACHESERVICE) {
- if (ha->cache_feat & GDT_64BIT) {
- /* copy elements from 32-bit IOCTL structure */
- gen.command.u.cache64.BlockCnt = gen.command.u.cache.BlockCnt;
- gen.command.u.cache64.BlockNo = gen.command.u.cache.BlockNo;
- gen.command.u.cache64.DeviceNo = gen.command.u.cache.DeviceNo;
- /* addresses */
- if (ha->cache_feat & SCATTER_GATHER) {
- gen.command.u.cache64.DestAddr = (u64)-1;
- gen.command.u.cache64.sg_canz = 1;
- gen.command.u.cache64.sg_lst[0].sg_ptr = paddr;
- gen.command.u.cache64.sg_lst[0].sg_len = gen.data_len;
- gen.command.u.cache64.sg_lst[1].sg_len = 0;
- } else {
- gen.command.u.cache64.DestAddr = paddr;
- gen.command.u.cache64.sg_canz = 0;
- }
- } else {
- if (ha->cache_feat & SCATTER_GATHER) {
- gen.command.u.cache.DestAddr = 0xffffffff;
- gen.command.u.cache.sg_canz = 1;
- gen.command.u.cache.sg_lst[0].sg_ptr = (u32)paddr;
- gen.command.u.cache.sg_lst[0].sg_len = gen.data_len;
- gen.command.u.cache.sg_lst[1].sg_len = 0;
- } else {
- gen.command.u.cache.DestAddr = paddr;
- gen.command.u.cache.sg_canz = 0;
- }
- }
- } else if (gen.command.Service == SCSIRAWSERVICE) {
- if (ha->raw_feat & GDT_64BIT) {
- /* copy elements from 32-bit IOCTL structure */
- char cmd[16];
- gen.command.u.raw64.sense_len = gen.command.u.raw.sense_len;
- gen.command.u.raw64.bus = gen.command.u.raw.bus;
- gen.command.u.raw64.lun = gen.command.u.raw.lun;
- gen.command.u.raw64.target = gen.command.u.raw.target;
- memcpy(cmd, gen.command.u.raw.cmd, 16);
- memcpy(gen.command.u.raw64.cmd, cmd, 16);
- gen.command.u.raw64.clen = gen.command.u.raw.clen;
- gen.command.u.raw64.sdlen = gen.command.u.raw.sdlen;
- gen.command.u.raw64.direction = gen.command.u.raw.direction;
- /* addresses */
- if (ha->raw_feat & SCATTER_GATHER) {
- gen.command.u.raw64.sdata = (u64)-1;
- gen.command.u.raw64.sg_ranz = 1;
- gen.command.u.raw64.sg_lst[0].sg_ptr = paddr;
- gen.command.u.raw64.sg_lst[0].sg_len = gen.data_len;
- gen.command.u.raw64.sg_lst[1].sg_len = 0;
- } else {
- gen.command.u.raw64.sdata = paddr;
- gen.command.u.raw64.sg_ranz = 0;
+static void gdth_ioc_scsiraw(gdth_ha_str *ha, gdth_ioctl_general *gen,
+ u64 paddr)
+{
+ if (ha->raw_feat & GDT_64BIT) {
+ /* copy elements from 32-bit IOCTL structure */
+ char cmd[16];
+
+ gen->command.u.raw64.sense_len = gen->command.u.raw.sense_len;
+ gen->command.u.raw64.bus = gen->command.u.raw.bus;
+ gen->command.u.raw64.lun = gen->command.u.raw.lun;
+ gen->command.u.raw64.target = gen->command.u.raw.target;
+ memcpy(cmd, gen->command.u.raw.cmd, 16);
+ memcpy(gen->command.u.raw64.cmd, cmd, 16);
+ gen->command.u.raw64.clen = gen->command.u.raw.clen;
+ gen->command.u.raw64.sdlen = gen->command.u.raw.sdlen;
+ gen->command.u.raw64.direction = gen->command.u.raw.direction;
+
+ /* addresses */
+ if (ha->raw_feat & SCATTER_GATHER) {
+ gen->command.u.raw64.sdata = (u64)-1;
+ gen->command.u.raw64.sg_ranz = 1;
+ gen->command.u.raw64.sg_lst[0].sg_ptr = paddr;
+ gen->command.u.raw64.sg_lst[0].sg_len = gen->data_len;
+ gen->command.u.raw64.sg_lst[1].sg_len = 0;
+ } else {
+ gen->command.u.raw64.sdata = paddr;
+ gen->command.u.raw64.sg_ranz = 0;
}
- gen.command.u.raw64.sense_data = paddr + gen.data_len;
- } else {
- if (ha->raw_feat & SCATTER_GATHER) {
- gen.command.u.raw.sdata = 0xffffffff;
- gen.command.u.raw.sg_ranz = 1;
- gen.command.u.raw.sg_lst[0].sg_ptr = (u32)paddr;
- gen.command.u.raw.sg_lst[0].sg_len = gen.data_len;
- gen.command.u.raw.sg_lst[1].sg_len = 0;
- } else {
- gen.command.u.raw.sdata = paddr;
- gen.command.u.raw.sg_ranz = 0;
+
+ gen->command.u.raw64.sense_data = paddr + gen->data_len;
+ } else {
+ if (ha->raw_feat & SCATTER_GATHER) {
+ gen->command.u.raw.sdata = 0xffffffff;
+ gen->command.u.raw.sg_ranz = 1;
+ gen->command.u.raw.sg_lst[0].sg_ptr = (u32)paddr;
+ gen->command.u.raw.sg_lst[0].sg_len = gen->data_len;
+ gen->command.u.raw.sg_lst[1].sg_len = 0;
+ } else {
+ gen->command.u.raw.sdata = paddr;
+ gen->command.u.raw.sg_ranz = 0;
}
- gen.command.u.raw.sense_data = (u32)paddr + gen.data_len;
- }
- } else {
- gdth_ioctl_free(ha, gen.data_len+gen.sense_len, buf, paddr);
- return -EFAULT;
- }
- }
- rval = __gdth_execute(ha->sdev, &gen.command, cmnd, gen.timeout, &gen.info);
- if (rval < 0) {
- gdth_ioctl_free(ha, gen.data_len+gen.sense_len, buf, paddr);
- return rval;
- }
- gen.status = rval;
+ gen->command.u.raw.sense_data = (u32)paddr + gen->data_len;
+ }
+}
- if (copy_to_user(arg + sizeof(gdth_ioctl_general), buf,
- gen.data_len + gen.sense_len)) {
- gdth_ioctl_free(ha, gen.data_len+gen.sense_len, buf, paddr);
- return -EFAULT;
- }
- if (copy_to_user(arg, &gen,
- sizeof(gdth_ioctl_general) - sizeof(gdth_cmd_str))) {
- gdth_ioctl_free(ha, gen.data_len+gen.sense_len, buf, paddr);
- return -EFAULT;
- }
- gdth_ioctl_free(ha, gen.data_len+gen.sense_len, buf, paddr);
- return 0;
+static int ioc_general(void __user *arg, char *cmnd)
+{
+ gdth_ioctl_general gen;
+ gdth_ha_str *ha;
+ char *buf = NULL;
+ dma_addr_t paddr;
+ int rval;
+
+ if (copy_from_user(&gen, arg, sizeof(gdth_ioctl_general)))
+ return -EFAULT;
+ ha = gdth_find_ha(gen.ionode);
+ if (!ha)
+ return -EFAULT;
+
+ if (gen.data_len > INT_MAX)
+ return -EINVAL;
+ if (gen.sense_len > INT_MAX)
+ return -EINVAL;
+ if (gen.data_len + gen.sense_len > INT_MAX)
+ return -EINVAL;
+
+ if (gen.data_len + gen.sense_len > 0) {
+ buf = dma_alloc_coherent(&ha->pdev->dev,
+ gen.data_len + gen.sense_len, &paddr,
+ GFP_KERNEL);
+ if (!buf)
+ return -EFAULT;
+
+ rval = -EFAULT;
+ if (copy_from_user(buf, arg + sizeof(gdth_ioctl_general),
+ gen.data_len + gen.sense_len))
+ goto out_free_buf;
+
+ if (gen.command.OpCode == GDT_IOCTL)
+ gen.command.u.ioctl.p_param = paddr;
+ else if (gen.command.Service == CACHESERVICE)
+ gdth_ioc_cacheservice(ha, &gen, paddr);
+ else if (gen.command.Service == SCSIRAWSERVICE)
+ gdth_ioc_scsiraw(ha, &gen, paddr);
+ else
+ goto out_free_buf;
+ }
+
+ rval = __gdth_execute(ha->sdev, &gen.command, cmnd, gen.timeout,
+ &gen.info);
+ if (rval < 0)
+ goto out_free_buf;
+ gen.status = rval;
+
+ rval = -EFAULT;
+ if (copy_to_user(arg + sizeof(gdth_ioctl_general), buf,
+ gen.data_len + gen.sense_len))
+ goto out_free_buf;
+ if (copy_to_user(arg, &gen,
+ sizeof(gdth_ioctl_general) - sizeof(gdth_cmd_str)))
+ goto out_free_buf;
+
+ rval = 0;
+out_free_buf:
+ dma_free_coherent(&ha->pdev->dev, gen.data_len + gen.sense_len, buf,
+ paddr);
+ return rval;
}
static int ioc_hdrlist(void __user *arg, char *cmnd)
@@ -4514,22 +3934,17 @@ static int gdth_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
(NULL == (ha = gdth_find_ha(ctrt.ionode))))
return -EFAULT;
- if (ha->type == GDT_ISA || ha->type == GDT_EISA) {
- ctrt.type = (u8)((ha->stype>>20) - 0x10);
+ if (ha->type != GDT_PCIMPR) {
+ ctrt.type = (u8)((ha->stype<<4) + 6);
} else {
- if (ha->type != GDT_PCIMPR) {
- ctrt.type = (u8)((ha->stype<<4) + 6);
- } else {
- ctrt.type =
- (ha->oem_id == OEM_ID_INTEL ? 0xfd : 0xfe);
- if (ha->stype >= 0x300)
- ctrt.ext_type = 0x6000 | ha->pdev->subsystem_device;
- else
- ctrt.ext_type = 0x6000 | ha->stype;
- }
- ctrt.device_id = ha->pdev->device;
- ctrt.sub_device_id = ha->pdev->subsystem_device;
+ ctrt.type = (ha->oem_id == OEM_ID_INTEL ? 0xfd : 0xfe);
+ if (ha->stype >= 0x300)
+ ctrt.ext_type = 0x6000 | ha->pdev->subsystem_device;
+ else
+ ctrt.ext_type = 0x6000 | ha->stype;
}
+ ctrt.device_id = ha->pdev->device;
+ ctrt.sub_device_id = ha->pdev->subsystem_device;
ctrt.info = ha->brd_phys;
ctrt.oem_id = ha->oem_id;
if (copy_to_user(argp, &ctrt, sizeof(gdth_ioctl_ctrtype)))
@@ -4683,272 +4098,6 @@ static struct scsi_host_template gdth_template = {
.no_write_same = 1,
};
-#ifdef CONFIG_ISA
-static int __init gdth_isa_probe_one(u32 isa_bios)
-{
- struct Scsi_Host *shp;
- gdth_ha_str *ha;
- dma_addr_t scratch_dma_handle = 0;
- int error, i;
-
- if (!gdth_search_isa(isa_bios))
- return -ENXIO;
-
- shp = scsi_host_alloc(&gdth_template, sizeof(gdth_ha_str));
- if (!shp)
- return -ENOMEM;
- ha = shost_priv(shp);
-
- error = -ENODEV;
- if (!gdth_init_isa(isa_bios,ha))
- goto out_host_put;
-
- /* controller found and initialized */
- printk("Configuring GDT-ISA HA at BIOS 0x%05X IRQ %u DRQ %u\n",
- isa_bios, ha->irq, ha->drq);
-
- error = request_irq(ha->irq, gdth_interrupt, 0, "gdth", ha);
- if (error) {
- printk("GDT-ISA: Unable to allocate IRQ\n");
- goto out_host_put;
- }
-
- error = request_dma(ha->drq, "gdth");
- if (error) {
- printk("GDT-ISA: Unable to allocate DMA channel\n");
- goto out_free_irq;
- }
-
- set_dma_mode(ha->drq,DMA_MODE_CASCADE);
- enable_dma(ha->drq);
- shp->unchecked_isa_dma = 1;
- shp->irq = ha->irq;
- shp->dma_channel = ha->drq;
-
- ha->hanum = gdth_ctr_count++;
- ha->shost = shp;
-
- ha->pccb = &ha->cmdext;
- ha->ccb_phys = 0L;
- ha->pdev = NULL;
-
- error = -ENOMEM;
-
- ha->pscratch = pci_alloc_consistent(ha->pdev, GDTH_SCRATCH,
- &scratch_dma_handle);
- if (!ha->pscratch)
- goto out_dec_counters;
- ha->scratch_phys = scratch_dma_handle;
-
- ha->pmsg = pci_alloc_consistent(ha->pdev, sizeof(gdth_msg_str),
- &scratch_dma_handle);
- if (!ha->pmsg)
- goto out_free_pscratch;
- ha->msg_phys = scratch_dma_handle;
-
-#ifdef INT_COAL
- ha->coal_stat = pci_alloc_consistent(ha->pdev,
- sizeof(gdth_coal_status) * MAXOFFSETS,
- &scratch_dma_handle);
- if (!ha->coal_stat)
- goto out_free_pmsg;
- ha->coal_stat_phys = scratch_dma_handle;
-#endif
-
- ha->scratch_busy = FALSE;
- ha->req_first = NULL;
- ha->tid_cnt = MAX_HDRIVES;
- if (max_ids > 0 && max_ids < ha->tid_cnt)
- ha->tid_cnt = max_ids;
- for (i = 0; i < GDTH_MAXCMDS; ++i)
- ha->cmd_tab[i].cmnd = UNUSED_CMND;
- ha->scan_mode = rescan ? 0x10 : 0;
-
- error = -ENODEV;
- if (!gdth_search_drives(ha)) {
- printk("GDT-ISA: Error during device scan\n");
- goto out_free_coal_stat;
- }
-
- if (hdr_channel < 0 || hdr_channel > ha->bus_cnt)
- hdr_channel = ha->bus_cnt;
- ha->virt_bus = hdr_channel;
-
- if (ha->cache_feat & ha->raw_feat & ha->screen_feat & GDT_64BIT)
- shp->max_cmd_len = 16;
-
- shp->max_id = ha->tid_cnt;
- shp->max_lun = MAXLUN;
- shp->max_channel = ha->bus_cnt;
-
- spin_lock_init(&ha->smp_lock);
- gdth_enable_int(ha);
-
- error = scsi_add_host(shp, NULL);
- if (error)
- goto out_free_coal_stat;
- list_add_tail(&ha->list, &gdth_instances);
- gdth_timer_init();
-
- scsi_scan_host(shp);
-
- return 0;
-
- out_free_coal_stat:
-#ifdef INT_COAL
- pci_free_consistent(ha->pdev, sizeof(gdth_coal_status) * MAXOFFSETS,
- ha->coal_stat, ha->coal_stat_phys);
- out_free_pmsg:
-#endif
- pci_free_consistent(ha->pdev, sizeof(gdth_msg_str),
- ha->pmsg, ha->msg_phys);
- out_free_pscratch:
- pci_free_consistent(ha->pdev, GDTH_SCRATCH,
- ha->pscratch, ha->scratch_phys);
- out_dec_counters:
- gdth_ctr_count--;
- out_free_irq:
- free_irq(ha->irq, ha);
- out_host_put:
- scsi_host_put(shp);
- return error;
-}
-#endif /* CONFIG_ISA */
-
-#ifdef CONFIG_EISA
-static int __init gdth_eisa_probe_one(u16 eisa_slot)
-{
- struct Scsi_Host *shp;
- gdth_ha_str *ha;
- dma_addr_t scratch_dma_handle = 0;
- int error, i;
-
- if (!gdth_search_eisa(eisa_slot))
- return -ENXIO;
-
- shp = scsi_host_alloc(&gdth_template, sizeof(gdth_ha_str));
- if (!shp)
- return -ENOMEM;
- ha = shost_priv(shp);
-
- error = -ENODEV;
- if (!gdth_init_eisa(eisa_slot,ha))
- goto out_host_put;
-
- /* controller found and initialized */
- printk("Configuring GDT-EISA HA at Slot %d IRQ %u\n",
- eisa_slot >> 12, ha->irq);
-
- error = request_irq(ha->irq, gdth_interrupt, 0, "gdth", ha);
- if (error) {
- printk("GDT-EISA: Unable to allocate IRQ\n");
- goto out_host_put;
- }
-
- shp->unchecked_isa_dma = 0;
- shp->irq = ha->irq;
- shp->dma_channel = 0xff;
-
- ha->hanum = gdth_ctr_count++;
- ha->shost = shp;
-
- TRACE2(("EISA detect Bus 0: hanum %d\n", ha->hanum));
-
- ha->pccb = &ha->cmdext;
- ha->ccb_phys = 0L;
-
- error = -ENOMEM;
-
- ha->pdev = NULL;
- ha->pscratch = pci_alloc_consistent(ha->pdev, GDTH_SCRATCH,
- &scratch_dma_handle);
- if (!ha->pscratch)
- goto out_free_irq;
- ha->scratch_phys = scratch_dma_handle;
-
- ha->pmsg = pci_alloc_consistent(ha->pdev, sizeof(gdth_msg_str),
- &scratch_dma_handle);
- if (!ha->pmsg)
- goto out_free_pscratch;
- ha->msg_phys = scratch_dma_handle;
-
-#ifdef INT_COAL
- ha->coal_stat = pci_alloc_consistent(ha->pdev,
- sizeof(gdth_coal_status) * MAXOFFSETS,
- &scratch_dma_handle);
- if (!ha->coal_stat)
- goto out_free_pmsg;
- ha->coal_stat_phys = scratch_dma_handle;
-#endif
-
- ha->ccb_phys = pci_map_single(ha->pdev,ha->pccb,
- sizeof(gdth_cmd_str), PCI_DMA_BIDIRECTIONAL);
- if (!ha->ccb_phys)
- goto out_free_coal_stat;
-
- ha->scratch_busy = FALSE;
- ha->req_first = NULL;
- ha->tid_cnt = MAX_HDRIVES;
- if (max_ids > 0 && max_ids < ha->tid_cnt)
- ha->tid_cnt = max_ids;
- for (i = 0; i < GDTH_MAXCMDS; ++i)
- ha->cmd_tab[i].cmnd = UNUSED_CMND;
- ha->scan_mode = rescan ? 0x10 : 0;
-
- if (!gdth_search_drives(ha)) {
- printk("GDT-EISA: Error during device scan\n");
- error = -ENODEV;
- goto out_free_ccb_phys;
- }
-
- if (hdr_channel < 0 || hdr_channel > ha->bus_cnt)
- hdr_channel = ha->bus_cnt;
- ha->virt_bus = hdr_channel;
-
- if (ha->cache_feat & ha->raw_feat & ha->screen_feat & GDT_64BIT)
- shp->max_cmd_len = 16;
-
- shp->max_id = ha->tid_cnt;
- shp->max_lun = MAXLUN;
- shp->max_channel = ha->bus_cnt;
-
- spin_lock_init(&ha->smp_lock);
- gdth_enable_int(ha);
-
- error = scsi_add_host(shp, NULL);
- if (error)
- goto out_free_ccb_phys;
- list_add_tail(&ha->list, &gdth_instances);
- gdth_timer_init();
-
- scsi_scan_host(shp);
-
- return 0;
-
- out_free_ccb_phys:
- pci_unmap_single(ha->pdev,ha->ccb_phys, sizeof(gdth_cmd_str),
- PCI_DMA_BIDIRECTIONAL);
- out_free_coal_stat:
-#ifdef INT_COAL
- pci_free_consistent(ha->pdev, sizeof(gdth_coal_status) * MAXOFFSETS,
- ha->coal_stat, ha->coal_stat_phys);
- out_free_pmsg:
-#endif
- pci_free_consistent(ha->pdev, sizeof(gdth_msg_str),
- ha->pmsg, ha->msg_phys);
- out_free_pscratch:
- pci_free_consistent(ha->pdev, GDTH_SCRATCH,
- ha->pscratch, ha->scratch_phys);
- out_free_irq:
- free_irq(ha->irq, ha);
- gdth_ctr_count--;
- out_host_put:
- scsi_host_put(shp);
- return error;
-}
-#endif /* CONFIG_EISA */
-
-#ifdef CONFIG_PCI
static int gdth_pci_probe_one(gdth_pci_str *pcistr, gdth_ha_str **ha_out)
{
struct Scsi_Host *shp;
@@ -4993,27 +4142,18 @@ static int gdth_pci_probe_one(gdth_pci_str *pcistr, gdth_ha_str **ha_out)
error = -ENOMEM;
- ha->pscratch = pci_alloc_consistent(ha->pdev, GDTH_SCRATCH,
- &scratch_dma_handle);
+ ha->pscratch = dma_alloc_coherent(&ha->pdev->dev, GDTH_SCRATCH,
+ &scratch_dma_handle, GFP_KERNEL);
if (!ha->pscratch)
goto out_free_irq;
ha->scratch_phys = scratch_dma_handle;
- ha->pmsg = pci_alloc_consistent(ha->pdev, sizeof(gdth_msg_str),
- &scratch_dma_handle);
+ ha->pmsg = dma_alloc_coherent(&ha->pdev->dev, sizeof(gdth_msg_str),
+ &scratch_dma_handle, GFP_KERNEL);
if (!ha->pmsg)
goto out_free_pscratch;
ha->msg_phys = scratch_dma_handle;
-#ifdef INT_COAL
- ha->coal_stat = pci_alloc_consistent(ha->pdev,
- sizeof(gdth_coal_status) * MAXOFFSETS,
- &scratch_dma_handle);
- if (!ha->coal_stat)
- goto out_free_pmsg;
- ha->coal_stat_phys = scratch_dma_handle;
-#endif
-
ha->scratch_busy = FALSE;
ha->req_first = NULL;
ha->tid_cnt = pdev->device >= 0x200 ? MAXID : MAX_HDRIVES;
@@ -5026,7 +4166,7 @@ static int gdth_pci_probe_one(gdth_pci_str *pcistr, gdth_ha_str **ha_out)
error = -ENODEV;
if (!gdth_search_drives(ha)) {
printk("GDT-PCI %d: Error during device scan\n", ha->hanum);
- goto out_free_coal_stat;
+ goto out_free_pmsg;
}
if (hdr_channel < 0 || hdr_channel > ha->bus_cnt)
@@ -5036,19 +4176,19 @@ static int gdth_pci_probe_one(gdth_pci_str *pcistr, gdth_ha_str **ha_out)
/* 64-bit DMA only supported from FW >= x.43 */
if (!(ha->cache_feat & ha->raw_feat & ha->screen_feat & GDT_64BIT) ||
!ha->dma64_support) {
- if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
+ if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(32))) {
printk(KERN_WARNING "GDT-PCI %d: "
"Unable to set 32-bit DMA\n", ha->hanum);
- goto out_free_coal_stat;
+ goto out_free_pmsg;
}
} else {
shp->max_cmd_len = 16;
- if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
+ if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(64))) {
printk("GDT-PCI %d: 64-bit DMA enabled\n", ha->hanum);
- } else if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
+ } else if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(32))) {
printk(KERN_WARNING "GDT-PCI %d: "
"Unable to set 64/32-bit DMA\n", ha->hanum);
- goto out_free_coal_stat;
+ goto out_free_pmsg;
}
}
@@ -5061,7 +4201,7 @@ static int gdth_pci_probe_one(gdth_pci_str *pcistr, gdth_ha_str **ha_out)
error = scsi_add_host(shp, &pdev->dev);
if (error)
- goto out_free_coal_stat;
+ goto out_free_pmsg;
list_add_tail(&ha->list, &gdth_instances);
pci_set_drvdata(ha->pdev, ha);
@@ -5073,16 +4213,11 @@ static int gdth_pci_probe_one(gdth_pci_str *pcistr, gdth_ha_str **ha_out)
return 0;
- out_free_coal_stat:
-#ifdef INT_COAL
- pci_free_consistent(ha->pdev, sizeof(gdth_coal_status) * MAXOFFSETS,
- ha->coal_stat, ha->coal_stat_phys);
out_free_pmsg:
-#endif
- pci_free_consistent(ha->pdev, sizeof(gdth_msg_str),
+ dma_free_coherent(&ha->pdev->dev, sizeof(gdth_msg_str),
ha->pmsg, ha->msg_phys);
out_free_pscratch:
- pci_free_consistent(ha->pdev, GDTH_SCRATCH,
+ dma_free_coherent(&ha->pdev->dev, GDTH_SCRATCH,
ha->pscratch, ha->scratch_phys);
out_free_irq:
free_irq(ha->irq, ha);
@@ -5091,7 +4226,6 @@ static int gdth_pci_probe_one(gdth_pci_str *pcistr, gdth_ha_str **ha_out)
scsi_host_put(shp);
return error;
}
-#endif /* CONFIG_PCI */
static void gdth_remove_one(gdth_ha_str *ha)
{
@@ -5111,24 +4245,15 @@ static void gdth_remove_one(gdth_ha_str *ha)
if (shp->irq)
free_irq(shp->irq,ha);
-#ifdef CONFIG_ISA
- if (shp->dma_channel != 0xff)
- free_dma(shp->dma_channel);
-#endif
-#ifdef INT_COAL
- if (ha->coal_stat)
- pci_free_consistent(ha->pdev, sizeof(gdth_coal_status) *
- MAXOFFSETS, ha->coal_stat, ha->coal_stat_phys);
-#endif
if (ha->pscratch)
- pci_free_consistent(ha->pdev, GDTH_SCRATCH,
+ dma_free_coherent(&ha->pdev->dev, GDTH_SCRATCH,
ha->pscratch, ha->scratch_phys);
if (ha->pmsg)
- pci_free_consistent(ha->pdev, sizeof(gdth_msg_str),
+ dma_free_coherent(&ha->pdev->dev, sizeof(gdth_msg_str),
ha->pmsg, ha->msg_phys);
if (ha->ccb_phys)
- pci_unmap_single(ha->pdev,ha->ccb_phys,
- sizeof(gdth_cmd_str),PCI_DMA_BIDIRECTIONAL);
+ dma_unmap_single(&ha->pdev->dev, ha->ccb_phys,
+ sizeof(gdth_cmd_str), DMA_BIDIRECTIONAL);
scsi_host_put(shp);
}
@@ -5167,26 +4292,6 @@ static int __init gdth_init(void)
gdth_clear_events();
timer_setup(&gdth_timer, gdth_timeout, 0);
- /* As default we do not probe for EISA or ISA controllers */
- if (probe_eisa_isa) {
- /* scanning for controllers, at first: ISA controller */
-#ifdef CONFIG_ISA
- u32 isa_bios;
- for (isa_bios = 0xc8000UL; isa_bios <= 0xd8000UL;
- isa_bios += 0x8000UL)
- gdth_isa_probe_one(isa_bios);
-#endif
-#ifdef CONFIG_EISA
- {
- u16 eisa_slot;
- for (eisa_slot = 0x1000; eisa_slot <= 0x8000;
- eisa_slot += 0x1000)
- gdth_eisa_probe_one(eisa_slot);
- }
-#endif
- }
-
-#ifdef CONFIG_PCI
/* scanning for PCI controllers */
if (pci_register_driver(&gdth_pci_driver)) {
gdth_ha_str *ha;
@@ -5195,7 +4300,6 @@ static int __init gdth_init(void)
gdth_remove_one(ha);
return -ENODEV;
}
-#endif /* CONFIG_PCI */
TRACE2(("gdth_detect() %d controller detected\n", gdth_ctr_count));
@@ -5216,9 +4320,7 @@ static void __exit gdth_exit(void)
del_timer_sync(&gdth_timer);
#endif
-#ifdef CONFIG_PCI
pci_unregister_driver(&gdth_pci_driver);
-#endif
list_for_each_entry(ha, &gdth_instances, list)
gdth_remove_one(ha);
diff --git a/drivers/scsi/gdth.h b/drivers/scsi/gdth.h
index ee6ffcf388e8..5a13d406d40e 100644
--- a/drivers/scsi/gdth.h
+++ b/drivers/scsi/gdth.h
@@ -38,17 +38,9 @@
#define OEM_ID_INTEL 0x8000
/* controller classes */
-#define GDT_ISA 0x01 /* ISA controller */
-#define GDT_EISA 0x02 /* EISA controller */
#define GDT_PCI 0x03 /* PCI controller */
#define GDT_PCINEW 0x04 /* new PCI controller */
#define GDT_PCIMPR 0x05 /* PCI MPR controller */
-/* GDT_EISA, controller subtypes EISA */
-#define GDT3_ID 0x0130941c /* GDT3000/3020 */
-#define GDT3A_ID 0x0230941c /* GDT3000A/3020A/3050A */
-#define GDT3B_ID 0x0330941c /* GDT3000B/3010A */
-/* GDT_ISA */
-#define GDT2_ID 0x0120941c /* GDT2000/2020 */
#ifndef PCI_DEVICE_ID_VORTEX_GDT60x0
/* GDT_PCI */
@@ -281,17 +273,6 @@
#define GDTH_DATA_IN 0x01000000L /* data from target */
#define GDTH_DATA_OUT 0x00000000L /* data to target */
-/* BMIC registers (EISA controllers) */
-#define ID0REG 0x0c80 /* board ID */
-#define EINTENABREG 0x0c89 /* interrupt enable */
-#define SEMA0REG 0x0c8a /* command semaphore */
-#define SEMA1REG 0x0c8b /* status semaphore */
-#define LDOORREG 0x0c8d /* local doorbell */
-#define EDENABREG 0x0c8e /* EISA system doorbell enab. */
-#define EDOORREG 0x0c8f /* EISA system doorbell */
-#define MAILBOXREG 0x0c90 /* mailbox reg. (16 bytes) */
-#define EISAREG 0x0cc0 /* EISA configuration */
-
/* other defines */
#define LINUX_OS 8 /* used for cache optim. */
#define SECS32 0x1f /* round capacity */
@@ -706,21 +687,11 @@ typedef struct {
u8 fw_magic; /* contr. ID from firmware */
} __attribute__((packed)) gdt_pci_sram;
-/* SRAM structure EISA controllers (but NOT GDT3000/3020) */
-typedef struct {
- u8 os_used[16]; /* OS code per service */
- u16 need_deinit; /* switch betw. BIOS/driver */
- u8 switch_support; /* see need_deinit */
- u8 padding;
-} __attribute__((packed)) gdt_eisa_sram;
-
-
/* DPRAM ISA controllers */
typedef struct {
union {
struct {
u8 bios_used[0x3c00-32]; /* 15KB - 32Bytes BIOS */
- u32 magic; /* controller (EISA) ID */
u16 need_deinit; /* switch betw. BIOS/driver */
u8 switch_support; /* see need_deinit */
u8 padding[9];
@@ -843,7 +814,6 @@ typedef struct {
u16 cache_feat; /* feat. cache serv. (s/g,..)*/
u16 raw_feat; /* feat. raw service (s/g,..)*/
u16 screen_feat; /* feat. raw service (s/g,..)*/
- u16 bmic; /* BMIC address (EISA) */
void __iomem *brd; /* DPRAM address */
u32 brd_phys; /* slot number/BIOS address */
gdt6c_plx_regs *plx; /* PLX regs (new PCI contr.) */
diff --git a/drivers/scsi/gdth_ioctl.h b/drivers/scsi/gdth_ioctl.h
index 4c91894ac244..ee4c9bf1022a 100644
--- a/drivers/scsi/gdth_ioctl.h
+++ b/drivers/scsi/gdth_ioctl.h
@@ -27,11 +27,7 @@
#define GDTH_MAXSG 32 /* max. s/g elements */
#define MAX_LDRIVES 255 /* max. log. drive count */
-#ifdef GDTH_IOCTL_PROC
-#define MAX_HDRIVES 100 /* max. host drive count */
-#else
#define MAX_HDRIVES MAX_LDRIVES /* max. host drive count */
-#endif
/* scatter/gather element */
typedef struct {
@@ -178,91 +174,6 @@ typedef struct {
gdth_evt_data event_data;
} __attribute__((packed)) gdth_evt_str;
-
-#ifdef GDTH_IOCTL_PROC
-/* IOCTL structure (write) */
-typedef struct {
- u32 magic; /* IOCTL magic */
- u16 ioctl; /* IOCTL */
- u16 ionode; /* controller number */
- u16 service; /* controller service */
- u16 timeout; /* timeout */
- union {
- struct {
- u8 command[512]; /* controller command */
- u8 data[1]; /* add. data */
- } general;
- struct {
- u8 lock; /* lock/unlock */
- u8 drive_cnt; /* drive count */
- u16 drives[MAX_HDRIVES];/* drives */
- } lockdrv;
- struct {
- u8 lock; /* lock/unlock */
- u8 channel; /* channel */
- } lockchn;
- struct {
- int erase; /* erase event ? */
- int handle;
- u8 evt[EVENT_SIZE]; /* event structure */
- } event;
- struct {
- u8 bus; /* SCSI bus */
- u8 target; /* target ID */
- u8 lun; /* LUN */
- u8 cmd_len; /* command length */
- u8 cmd[12]; /* SCSI command */
- } scsi;
- struct {
- u16 hdr_no; /* host drive number */
- u8 flag; /* old meth./add/remove */
- } rescan;
- } iu;
-} gdth_iowr_str;
-
-/* IOCTL structure (read) */
-typedef struct {
- u32 size; /* buffer size */
- u32 status; /* IOCTL error code */
- union {
- struct {
- u8 data[1]; /* data */
- } general;
- struct {
- u16 version; /* driver version */
- } drvers;
- struct {
- u8 type; /* controller type */
- u16 info; /* slot etc. */
- u16 oem_id; /* OEM ID */
- u16 bios_ver; /* not used */
- u16 access; /* not used */
- u16 ext_type; /* extended type */
- u16 device_id; /* device ID */
- u16 sub_device_id; /* sub device ID */
- } ctrtype;
- struct {
- u8 version; /* OS version */
- u8 subversion; /* OS subversion */
- u16 revision; /* revision */
- } osvers;
- struct {
- u16 count; /* controller count */
- } ctrcnt;
- struct {
- int handle;
- u8 evt[EVENT_SIZE]; /* event structure */
- } event;
- struct {
- u8 bus; /* SCSI bus, 0xff: invalid */
- u8 target; /* target ID */
- u8 lun; /* LUN */
- u8 cluster_type; /* cluster properties */
- } hdr_list[MAX_HDRIVES]; /* index is host drive number */
- } iu;
-} gdth_iord_str;
-#endif
-
/* GDTIOCTL_GENERAL */
typedef struct {
u16 ionode; /* controller number */
diff --git a/drivers/scsi/gdth_proc.c b/drivers/scsi/gdth_proc.c
index 3a9751a80225..381d849726ac 100644
--- a/drivers/scsi/gdth_proc.c
+++ b/drivers/scsi/gdth_proc.c
@@ -31,7 +31,6 @@ static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer,
int i, found;
gdth_cmd_str gdtcmd;
gdth_cpar_str *pcpar;
- u64 paddr;
char cmnd[MAX_COMMAND_SIZE];
memset(cmnd, 0xff, 12);
@@ -113,13 +112,23 @@ static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer,
}
if (wb_mode) {
- if (!gdth_ioctl_alloc(ha, sizeof(gdth_cpar_str), TRUE, &paddr))
- return(-EBUSY);
+ unsigned long flags;
+
+ BUILD_BUG_ON(sizeof(gdth_cpar_str) > GDTH_SCRATCH);
+
+ spin_lock_irqsave(&ha->smp_lock, flags);
+ if (ha->scratch_busy) {
+ spin_unlock_irqrestore(&ha->smp_lock, flags);
+ return -EBUSY;
+ }
+ ha->scratch_busy = TRUE;
+ spin_unlock_irqrestore(&ha->smp_lock, flags);
+
pcpar = (gdth_cpar_str *)ha->pscratch;
memcpy( pcpar, &ha->cpar, sizeof(gdth_cpar_str) );
gdtcmd.Service = CACHESERVICE;
gdtcmd.OpCode = GDT_IOCTL;
- gdtcmd.u.ioctl.p_param = paddr;
+ gdtcmd.u.ioctl.p_param = ha->scratch_phys;
gdtcmd.u.ioctl.param_size = sizeof(gdth_cpar_str);
gdtcmd.u.ioctl.subfunc = CACHE_CONFIG;
gdtcmd.u.ioctl.channel = INVALID_CHANNEL;
@@ -127,7 +136,10 @@ static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer,
gdth_execute(host, &gdtcmd, cmnd, 30, NULL);
- gdth_ioctl_free(ha, GDTH_SCRATCH, ha->pscratch, paddr);
+ spin_lock_irqsave(&ha->smp_lock, flags);
+ ha->scratch_busy = FALSE;
+ spin_unlock_irqrestore(&ha->smp_lock, flags);
+
printk("Done.\n");
return(orig_length);
}
@@ -143,7 +155,7 @@ int gdth_show_info(struct seq_file *m, struct Scsi_Host *host)
int id, i, j, k, sec, flag;
int no_mdrv = 0, drv_no, is_mirr;
u32 cnt;
- u64 paddr;
+ dma_addr_t paddr;
int rc = -ENOMEM;
gdth_cmd_str *gdtcmd;
@@ -217,20 +229,14 @@ int gdth_show_info(struct seq_file *m, struct Scsi_Host *host)
" Serial No.: \t0x%8X\tCache RAM size:\t%d KB\n",
ha->binfo.ser_no, ha->binfo.memsize / 1024);
-#ifdef GDTH_DMA_STATISTICS
- /* controller statistics */
- seq_puts(m, "\nController Statistics:\n");
- seq_printf(m,
- " 32-bit DMA buffer:\t%lu\t64-bit DMA buffer:\t%lu\n",
- ha->dma32_cnt, ha->dma64_cnt);
-#endif
-
if (ha->more_proc) {
+ size_t size = max_t(size_t, GDTH_SCRATCH, sizeof(gdth_hget_str));
+
/* more information: 2. about physical devices */
seq_puts(m, "\nPhysical Devices:");
flag = FALSE;
- buf = gdth_ioctl_alloc(ha, GDTH_SCRATCH, FALSE, &paddr);
+ buf = dma_alloc_coherent(&ha->pdev->dev, size, &paddr, GFP_KERNEL);
if (!buf)
goto stop_output;
for (i = 0; i < ha->bus_cnt; ++i) {
@@ -323,7 +329,6 @@ int gdth_show_info(struct seq_file *m, struct Scsi_Host *host)
}
}
}
- gdth_ioctl_free(ha, GDTH_SCRATCH, buf, paddr);
if (!flag)
seq_puts(m, "\n --\n");
@@ -332,9 +337,6 @@ int gdth_show_info(struct seq_file *m, struct Scsi_Host *host)
seq_puts(m, "\nLogical Drives:");
flag = FALSE;
- buf = gdth_ioctl_alloc(ha, GDTH_SCRATCH, FALSE, &paddr);
- if (!buf)
- goto stop_output;
for (i = 0; i < MAX_LDRIVES; ++i) {
if (!ha->hdr[i].is_logdrv)
continue;
@@ -408,8 +410,7 @@ int gdth_show_info(struct seq_file *m, struct Scsi_Host *host)
seq_printf(m,
" To Array Drv.:\t%s\n", hrec);
}
- gdth_ioctl_free(ha, GDTH_SCRATCH, buf, paddr);
-
+
if (!flag)
seq_puts(m, "\n --\n");
@@ -417,9 +418,6 @@ int gdth_show_info(struct seq_file *m, struct Scsi_Host *host)
seq_puts(m, "\nArray Drives:");
flag = FALSE;
- buf = gdth_ioctl_alloc(ha, GDTH_SCRATCH, FALSE, &paddr);
- if (!buf)
- goto stop_output;
for (i = 0; i < MAX_LDRIVES; ++i) {
if (!(ha->hdr[i].is_arraydrv && ha->hdr[i].is_master))
continue;
@@ -468,8 +466,7 @@ int gdth_show_info(struct seq_file *m, struct Scsi_Host *host)
hrec);
}
}
- gdth_ioctl_free(ha, GDTH_SCRATCH, buf, paddr);
-
+
if (!flag)
seq_puts(m, "\n --\n");
@@ -477,9 +474,6 @@ int gdth_show_info(struct seq_file *m, struct Scsi_Host *host)
seq_puts(m, "\nHost Drives:");
flag = FALSE;
- buf = gdth_ioctl_alloc(ha, sizeof(gdth_hget_str), FALSE, &paddr);
- if (!buf)
- goto stop_output;
for (i = 0; i < MAX_LDRIVES; ++i) {
if (!ha->hdr[i].is_logdrv ||
(ha->hdr[i].is_arraydrv && !ha->hdr[i].is_master))
@@ -510,7 +504,7 @@ int gdth_show_info(struct seq_file *m, struct Scsi_Host *host)
}
}
}
- gdth_ioctl_free(ha, sizeof(gdth_hget_str), buf, paddr);
+ dma_free_coherent(&ha->pdev->dev, size, buf, paddr);
for (i = 0; i < MAX_HDRIVES; ++i) {
if (!(ha->hdr[i].present))
@@ -563,65 +557,6 @@ free_fail:
return rc;
}
-static char *gdth_ioctl_alloc(gdth_ha_str *ha, int size, int scratch,
- u64 *paddr)
-{
- unsigned long flags;
- char *ret_val;
-
- if (size == 0)
- return NULL;
-
- spin_lock_irqsave(&ha->smp_lock, flags);
-
- if (!ha->scratch_busy && size <= GDTH_SCRATCH) {
- ha->scratch_busy = TRUE;
- ret_val = ha->pscratch;
- *paddr = ha->scratch_phys;
- } else if (scratch) {
- ret_val = NULL;
- } else {
- dma_addr_t dma_addr;
-
- ret_val = pci_alloc_consistent(ha->pdev, size, &dma_addr);
- *paddr = dma_addr;
- }
-
- spin_unlock_irqrestore(&ha->smp_lock, flags);
- return ret_val;
-}
-
-static void gdth_ioctl_free(gdth_ha_str *ha, int size, char *buf, u64 paddr)
-{
- unsigned long flags;
-
- if (buf == ha->pscratch) {
- spin_lock_irqsave(&ha->smp_lock, flags);
- ha->scratch_busy = FALSE;
- spin_unlock_irqrestore(&ha->smp_lock, flags);
- } else {
- pci_free_consistent(ha->pdev, size, buf, paddr);
- }
-}
-
-#ifdef GDTH_IOCTL_PROC
-static int gdth_ioctl_check_bin(gdth_ha_str *ha, u16 size)
-{
- unsigned long flags;
- int ret_val;
-
- spin_lock_irqsave(&ha->smp_lock, flags);
-
- ret_val = FALSE;
- if (ha->scratch_busy) {
- if (((gdth_iord_str *)ha->pscratch)->size == (u32)size)
- ret_val = TRUE;
- }
- spin_unlock_irqrestore(&ha->smp_lock, flags);
- return ret_val;
-}
-#endif
-
static void gdth_wait_completion(gdth_ha_str *ha, int busnum, int id)
{
unsigned long flags;
diff --git a/drivers/scsi/gdth_proc.h b/drivers/scsi/gdth_proc.h
index d7d0aa283695..4cc5377cb92e 100644
--- a/drivers/scsi/gdth_proc.h
+++ b/drivers/scsi/gdth_proc.h
@@ -12,9 +12,6 @@ int gdth_execute(struct Scsi_Host *shost, gdth_cmd_str *gdtcmd, char *cmnd,
static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer,
int length, gdth_ha_str *ha);
-static char *gdth_ioctl_alloc(gdth_ha_str *ha, int size, int scratch,
- u64 *paddr);
-static void gdth_ioctl_free(gdth_ha_str *ha, int size, char *buf, u64 paddr);
static void gdth_wait_completion(gdth_ha_str *ha, int busnum, int id);
#endif
diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h
index af291947a54d..6a1a5adc0878 100644
--- a/drivers/scsi/hisi_sas/hisi_sas.h
+++ b/drivers/scsi/hisi_sas/hisi_sas.h
@@ -14,6 +14,7 @@
#include <linux/acpi.h>
#include <linux/clk.h>
+#include <linux/debugfs.h>
#include <linux/dmapool.h>
#include <linux/iopoll.h>
#include <linux/lcm.h>
@@ -220,6 +221,24 @@ struct hisi_sas_slot {
u16 idx;
};
+#define HISI_SAS_DEBUGFS_REG(x) {#x, x}
+
+struct hisi_sas_debugfs_reg_lu {
+ char *name;
+ int off;
+};
+
+struct hisi_sas_debugfs_reg {
+ const struct hisi_sas_debugfs_reg_lu *lu;
+ int count;
+ int base_off;
+ union {
+ u32 (*read_global_reg)(struct hisi_hba *hisi_hba, u32 off);
+ u32 (*read_port_reg)(struct hisi_hba *hisi_hba, int port,
+ u32 off);
+ };
+};
+
struct hisi_sas_hw {
int (*hw_init)(struct hisi_hba *hisi_hba);
void (*setup_itct)(struct hisi_hba *hisi_hba,
@@ -259,11 +278,16 @@ struct hisi_sas_hw {
u32 (*get_phys_state)(struct hisi_hba *hisi_hba);
int (*write_gpio)(struct hisi_hba *hisi_hba, u8 reg_type,
u8 reg_index, u8 reg_count, u8 *write_data);
- void (*wait_cmds_complete_timeout)(struct hisi_hba *hisi_hba,
- int delay_ms, int timeout_ms);
+ int (*wait_cmds_complete_timeout)(struct hisi_hba *hisi_hba,
+ int delay_ms, int timeout_ms);
+ void (*snapshot_prepare)(struct hisi_hba *hisi_hba);
+ void (*snapshot_restore)(struct hisi_hba *hisi_hba);
int max_command_entries;
int complete_hdr_size;
struct scsi_host_template *sht;
+
+ const struct hisi_sas_debugfs_reg *debugfs_reg_global;
+ const struct hisi_sas_debugfs_reg *debugfs_reg_port;
};
struct hisi_hba {
@@ -329,9 +353,21 @@ struct hisi_hba {
const struct hisi_sas_hw *hw; /* Low level hw interface */
unsigned long sata_dev_bitmap[BITS_TO_LONGS(HISI_SAS_MAX_DEVICES)];
struct work_struct rst_work;
+ struct work_struct debugfs_work;
u32 phy_state;
u32 intr_coal_ticks; /* Time of interrupt coalesce in us */
u32 intr_coal_count; /* Interrupt count to coalesce */
+
+ /* debugfs memories */
+ void *debugfs_global_reg;
+ void *debugfs_port_reg[HISI_SAS_MAX_PHYS];
+ void *debugfs_complete_hdr[HISI_SAS_MAX_QUEUES];
+ struct hisi_sas_cmd_hdr *debugfs_cmd_hdr[HISI_SAS_MAX_QUEUES];
+ struct hisi_sas_iost *debugfs_iost;
+ struct hisi_sas_itct *debugfs_itct;
+
+ struct dentry *debugfs_dir;
+ struct dentry *debugfs_dump_dentry;
};
/* Generic HW DMA host memory structures */
@@ -461,6 +497,10 @@ struct hisi_sas_slot_buf_table {
};
extern struct scsi_transport_template *hisi_sas_stt;
+
+extern bool hisi_sas_debugfs_enable;
+extern struct dentry *hisi_sas_debugfs_dir;
+
extern void hisi_sas_stop_phys(struct hisi_hba *hisi_hba);
extern int hisi_sas_alloc(struct hisi_hba *hisi_hba, struct Scsi_Host *shost);
extern void hisi_sas_free(struct hisi_hba *hisi_hba);
@@ -493,4 +533,7 @@ extern void hisi_sas_release_tasks(struct hisi_hba *hisi_hba);
extern u8 hisi_sas_get_prog_phy_linkrate_mask(enum sas_linkrate max);
extern void hisi_sas_controller_reset_prepare(struct hisi_hba *hisi_hba);
extern void hisi_sas_controller_reset_done(struct hisi_hba *hisi_hba);
+extern void hisi_sas_debugfs_init(struct hisi_hba *hisi_hba);
+extern void hisi_sas_debugfs_exit(struct hisi_hba *hisi_hba);
+extern void hisi_sas_debugfs_work_handler(struct work_struct *work);
#endif
diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
index eed7fc5b3389..3d24366ceeef 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
@@ -1429,6 +1429,10 @@ static int hisi_sas_controller_reset(struct hisi_hba *hisi_hba)
struct Scsi_Host *shost = hisi_hba->shost;
int rc;
+ if (hisi_sas_debugfs_enable && hisi_hba->debugfs_itct &&
+ !hisi_hba->debugfs_dump_dentry)
+ queue_work(hisi_hba->wq, &hisi_hba->debugfs_work);
+
if (!hisi_hba->hw->soft_reset)
return -1;
@@ -1923,6 +1927,7 @@ hisi_sas_internal_task_abort(struct hisi_hba *hisi_hba,
slot->task = NULL;
}
dev_err(dev, "internal task abort: timeout and not done.\n");
+
res = -EIO;
goto exit;
} else
@@ -2457,6 +2462,499 @@ err_out_ha:
}
EXPORT_SYMBOL_GPL(hisi_sas_probe);
+struct dentry *hisi_sas_debugfs_dir;
+
+static void hisi_sas_debugfs_snapshot_cq_reg(struct hisi_hba *hisi_hba)
+{
+ int queue_entry_size = hisi_hba->hw->complete_hdr_size;
+ int i;
+
+ for (i = 0; i < hisi_hba->queue_count; i++)
+ memcpy(hisi_hba->debugfs_complete_hdr[i],
+ hisi_hba->complete_hdr[i],
+ HISI_SAS_QUEUE_SLOTS * queue_entry_size);
+}
+
+static void hisi_sas_debugfs_snapshot_dq_reg(struct hisi_hba *hisi_hba)
+{
+ int queue_entry_size = hisi_hba->hw->complete_hdr_size;
+ int i;
+
+ for (i = 0; i < hisi_hba->queue_count; i++)
+ memcpy(hisi_hba->debugfs_cmd_hdr[i],
+ hisi_hba->cmd_hdr[i],
+ HISI_SAS_QUEUE_SLOTS * queue_entry_size);
+}
+
+static void hisi_sas_debugfs_snapshot_port_reg(struct hisi_hba *hisi_hba)
+{
+ const struct hisi_sas_debugfs_reg *port =
+ hisi_hba->hw->debugfs_reg_port;
+ int i, phy_cnt;
+ u32 offset;
+ u32 *databuf;
+
+ for (phy_cnt = 0; phy_cnt < hisi_hba->n_phy; phy_cnt++) {
+ databuf = (u32 *)hisi_hba->debugfs_port_reg[phy_cnt];
+ for (i = 0; i < port->count; i++, databuf++) {
+ offset = port->base_off + 4 * i;
+ *databuf = port->read_port_reg(hisi_hba, phy_cnt,
+ offset);
+ }
+ }
+}
+
+static void hisi_sas_debugfs_snapshot_global_reg(struct hisi_hba *hisi_hba)
+{
+ u32 *databuf = (u32 *)hisi_hba->debugfs_global_reg;
+ const struct hisi_sas_debugfs_reg *global =
+ hisi_hba->hw->debugfs_reg_global;
+ int i;
+
+ for (i = 0; i < global->count; i++, databuf++)
+ *databuf = global->read_global_reg(hisi_hba, 4 * i);
+}
+
+static void hisi_sas_debugfs_snapshot_itct_reg(struct hisi_hba *hisi_hba)
+{
+ void *databuf = hisi_hba->debugfs_itct;
+ struct hisi_sas_itct *itct;
+ int i;
+
+ itct = hisi_hba->itct;
+
+ for (i = 0; i < HISI_SAS_MAX_ITCT_ENTRIES; i++, itct++) {
+ memcpy(databuf, itct, sizeof(struct hisi_sas_itct));
+ databuf += sizeof(struct hisi_sas_itct);
+ }
+}
+
+static void hisi_sas_debugfs_snapshot_iost_reg(struct hisi_hba *hisi_hba)
+{
+ int max_command_entries = hisi_hba->hw->max_command_entries;
+ void *databuf = hisi_hba->debugfs_iost;
+ struct hisi_sas_iost *iost;
+ int i;
+
+ iost = hisi_hba->iost;
+
+ for (i = 0; i < max_command_entries; i++, iost++) {
+ memcpy(databuf, iost, sizeof(struct hisi_sas_iost));
+ databuf += sizeof(struct hisi_sas_iost);
+ }
+}
+
+const char *
+hisi_sas_debugfs_to_reg_name(int off, int base_off,
+ const struct hisi_sas_debugfs_reg_lu *lu)
+{
+ for (; lu->name; lu++) {
+ if (off == lu->off - base_off)
+ return lu->name;
+ }
+
+ return NULL;
+}
+
+static void hisi_sas_debugfs_print_reg(u32 *regs_val, const void *ptr,
+ struct seq_file *s)
+{
+ const struct hisi_sas_debugfs_reg *reg = ptr;
+ int i;
+
+ for (i = 0; i < reg->count; i++) {
+ int off = i * 4;
+ const char *name;
+
+ name = hisi_sas_debugfs_to_reg_name(off, reg->base_off,
+ reg->lu);
+
+ if (name)
+ seq_printf(s, "0x%08x 0x%08x %s\n", off,
+ le32_to_cpu(regs_val[i]), name);
+ else
+ seq_printf(s, "0x%08x 0x%08x\n", off,
+ le32_to_cpu(regs_val[i]));
+ }
+}
+
+static int hisi_sas_debugfs_global_show(struct seq_file *s, void *p)
+{
+ struct hisi_hba *hisi_hba = s->private;
+ const struct hisi_sas_hw *hw = hisi_hba->hw;
+ const struct hisi_sas_debugfs_reg *reg_global = hw->debugfs_reg_global;
+
+ hisi_sas_debugfs_print_reg((u32 *)hisi_hba->debugfs_global_reg,
+ reg_global, s);
+
+ return 0;
+}
+
+static int hisi_sas_debugfs_global_open(struct inode *inode, struct file *filp)
+{
+ return single_open(filp, hisi_sas_debugfs_global_show,
+ inode->i_private);
+}
+
+static const struct file_operations hisi_sas_debugfs_global_fops = {
+ .open = hisi_sas_debugfs_global_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .owner = THIS_MODULE,
+};
+
+static int hisi_sas_debugfs_port_show(struct seq_file *s, void *p)
+{
+ struct hisi_sas_phy *phy = s->private;
+ struct hisi_hba *hisi_hba = phy->hisi_hba;
+ const struct hisi_sas_hw *hw = hisi_hba->hw;
+ const struct hisi_sas_debugfs_reg *reg_port = hw->debugfs_reg_port;
+ u32 *databuf = hisi_hba->debugfs_port_reg[phy->sas_phy.id];
+
+ hisi_sas_debugfs_print_reg(databuf, reg_port, s);
+
+ return 0;
+}
+
+static int hisi_sas_debugfs_port_open(struct inode *inode, struct file *filp)
+{
+ return single_open(filp, hisi_sas_debugfs_port_show, inode->i_private);
+}
+
+static const struct file_operations hisi_sas_debugfs_port_fops = {
+ .open = hisi_sas_debugfs_port_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .owner = THIS_MODULE,
+};
+
+static int hisi_sas_show_row_64(struct seq_file *s, int index,
+ int sz, u64 *ptr)
+{
+ int i;
+
+ /* completion header size not fixed per HW version */
+ seq_printf(s, "index %04d:\n\t", index);
+ for (i = 1; i <= sz / 8; i++, ptr++) {
+ seq_printf(s, " 0x%016llx", le64_to_cpu(*ptr));
+ if (!(i % 2))
+ seq_puts(s, "\n\t");
+ }
+
+ seq_puts(s, "\n");
+
+ return 0;
+}
+
+static int hisi_sas_show_row_32(struct seq_file *s, int index,
+ int sz, u32 *ptr)
+{
+ int i;
+
+ /* completion header size not fixed per HW version */
+ seq_printf(s, "index %04d:\n\t", index);
+ for (i = 1; i <= sz / 4; i++, ptr++) {
+ if (!(i % 4))
+ seq_puts(s, "\n\t");
+ }
+ seq_puts(s, "\n");
+
+ return 0;
+}
+
+static int hisi_sas_cq_show_slot(struct seq_file *s, int slot, void *cq_ptr)
+{
+ struct hisi_sas_cq *cq = cq_ptr;
+ struct hisi_hba *hisi_hba = cq->hisi_hba;
+ void *complete_queue = hisi_hba->debugfs_complete_hdr[cq->id];
+ void *complete_hdr = complete_queue +
+ (hisi_hba->hw->complete_hdr_size * slot);
+
+ return hisi_sas_show_row_32(s, slot,
+ hisi_hba->hw->complete_hdr_size,
+ complete_hdr);
+}
+
+static int hisi_sas_debugfs_cq_show(struct seq_file *s, void *p)
+{
+ struct hisi_sas_cq *cq = s->private;
+ int slot, ret;
+
+ for (slot = 0; slot < HISI_SAS_QUEUE_SLOTS; slot++) {
+ ret = hisi_sas_cq_show_slot(s, slot, cq);
+ if (ret)
+ return ret;
+ }
+ return 0;
+}
+
+static int hisi_sas_debugfs_cq_open(struct inode *inode, struct file *filp)
+{
+ return single_open(filp, hisi_sas_debugfs_cq_show, inode->i_private);
+}
+
+static const struct file_operations hisi_sas_debugfs_cq_fops = {
+ .open = hisi_sas_debugfs_cq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .owner = THIS_MODULE,
+};
+
+static int hisi_sas_dq_show_slot(struct seq_file *s, int slot, void *dq_ptr)
+{
+ struct hisi_sas_dq *dq = dq_ptr;
+ struct hisi_hba *hisi_hba = dq->hisi_hba;
+ void *cmd_queue = hisi_hba->debugfs_cmd_hdr[dq->id];
+ void *cmd_hdr = cmd_queue +
+ hisi_hba->hw->complete_hdr_size * slot;
+
+ return hisi_sas_show_row_32(s, slot, sizeof(struct hisi_sas_cmd_hdr),
+ cmd_hdr);
+}
+
+static int hisi_sas_debugfs_dq_show(struct seq_file *s, void *p)
+{
+ int slot, ret;
+
+ for (slot = 0; slot < HISI_SAS_QUEUE_SLOTS; slot++) {
+ ret = hisi_sas_dq_show_slot(s, slot, s->private);
+ if (ret)
+ return ret;
+ }
+ return 0;
+}
+
+static int hisi_sas_debugfs_dq_open(struct inode *inode, struct file *filp)
+{
+ return single_open(filp, hisi_sas_debugfs_dq_show, inode->i_private);
+}
+
+static const struct file_operations hisi_sas_debugfs_dq_fops = {
+ .open = hisi_sas_debugfs_dq_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .owner = THIS_MODULE,
+};
+
+static int hisi_sas_debugfs_iost_show(struct seq_file *s, void *p)
+{
+ struct hisi_hba *hisi_hba = s->private;
+ struct hisi_sas_iost *debugfs_iost = hisi_hba->debugfs_iost;
+ int i, ret, max_command_entries = hisi_hba->hw->max_command_entries;
+
+ for (i = 0; i < max_command_entries; i++, debugfs_iost++) {
+ ret = hisi_sas_show_row_64(s, i, sizeof(*debugfs_iost),
+ (u64 *)debugfs_iost);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int hisi_sas_debugfs_iost_open(struct inode *inode, struct file *filp)
+{
+ return single_open(filp, hisi_sas_debugfs_iost_show, inode->i_private);
+}
+
+static const struct file_operations hisi_sas_debugfs_iost_fops = {
+ .open = hisi_sas_debugfs_iost_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+ .owner = THIS_MODULE,
+};
+
+static void hisi_sas_debugfs_create_files(struct hisi_hba *hisi_hba)
+{
+ struct dentry *dump_dentry;
+ struct dentry *dentry;
+ char name[256];
+ int p;
+ int c;
+ int d;
+
+ /* Create dump dir inside device dir */
+ dump_dentry = debugfs_create_dir("dump", hisi_hba->debugfs_dir);
+ if (!dump_dentry)
+ goto fail;
+
+ hisi_hba->debugfs_dump_dentry = dump_dentry;
+
+ if (!debugfs_create_file("global", 0400, dump_dentry, hisi_hba,
+ &hisi_sas_debugfs_global_fops))
+ goto fail;
+
+ /* Create port dir and files */
+ dentry = debugfs_create_dir("port", dump_dentry);
+ if (!dentry)
+ goto fail;
+
+ for (p = 0; p < hisi_hba->n_phy; p++) {
+ snprintf(name, 256, "%d", p);
+ if (!debugfs_create_file(name, 0400, dentry,
+ &hisi_hba->phy[p],
+ &hisi_sas_debugfs_port_fops))
+ goto fail;
+ }
+
+ /* Create CQ dir and files */
+ dentry = debugfs_create_dir("cq", dump_dentry);
+ if (!dentry)
+ goto fail;
+
+ for (c = 0; c < hisi_hba->queue_count; c++) {
+ snprintf(name, 256, "%d", c);
+
+ if (!debugfs_create_file(name, 0400, dentry,
+ &hisi_hba->cq[c],
+ &hisi_sas_debugfs_cq_fops))
+ goto fail;
+ }
+
+ /* Create DQ dir and files */
+ dentry = debugfs_create_dir("dq", dump_dentry);
+ if (!dentry)
+ goto fail;
+
+ for (d = 0; d < hisi_hba->queue_count; d++) {
+ snprintf(name, 256, "%d", d);
+
+ if (!debugfs_create_file(name, 0400, dentry,
+ &hisi_hba->dq[d],
+ &hisi_sas_debugfs_dq_fops))
+ goto fail;
+ }
+
+ if (!debugfs_create_file("iost", 0400, dump_dentry, hisi_hba,
+ &hisi_sas_debugfs_iost_fops))
+ goto fail;
+
+ return;
+fail:
+ debugfs_remove_recursive(hisi_hba->debugfs_dir);
+}
+
+static void hisi_sas_debugfs_snapshot_regs(struct hisi_hba *hisi_hba)
+{
+ hisi_hba->hw->snapshot_prepare(hisi_hba);
+
+ hisi_sas_debugfs_snapshot_global_reg(hisi_hba);
+ hisi_sas_debugfs_snapshot_port_reg(hisi_hba);
+ hisi_sas_debugfs_snapshot_cq_reg(hisi_hba);
+ hisi_sas_debugfs_snapshot_dq_reg(hisi_hba);
+ hisi_sas_debugfs_snapshot_itct_reg(hisi_hba);
+ hisi_sas_debugfs_snapshot_iost_reg(hisi_hba);
+
+ hisi_sas_debugfs_create_files(hisi_hba);
+
+ hisi_hba->hw->snapshot_restore(hisi_hba);
+}
+
+void hisi_sas_debugfs_work_handler(struct work_struct *work)
+{
+ struct hisi_hba *hisi_hba =
+ container_of(work, struct hisi_hba, debugfs_work);
+
+ hisi_sas_debugfs_snapshot_regs(hisi_hba);
+}
+EXPORT_SYMBOL_GPL(hisi_sas_debugfs_work_handler);
+
+void hisi_sas_debugfs_init(struct hisi_hba *hisi_hba)
+{
+ int max_command_entries = hisi_hba->hw->max_command_entries;
+ struct device *dev = hisi_hba->dev;
+ int p, i, c, d;
+ size_t sz;
+
+ hisi_hba->debugfs_dir = debugfs_create_dir(dev_name(dev),
+ hisi_sas_debugfs_dir);
+
+ if (!hisi_hba->debugfs_dir)
+ return;
+
+ /* Alloc buffer for global */
+ sz = hisi_hba->hw->debugfs_reg_global->count * 4;
+ hisi_hba->debugfs_global_reg =
+ devm_kmalloc(dev, sz, GFP_KERNEL);
+
+ if (!hisi_hba->debugfs_global_reg)
+ goto fail_global;
+
+ /* Alloc buffer for port */
+ sz = hisi_hba->hw->debugfs_reg_port->count * 4;
+ for (p = 0; p < hisi_hba->n_phy; p++) {
+ hisi_hba->debugfs_port_reg[p] =
+ devm_kmalloc(dev, sz, GFP_KERNEL);
+
+ if (!hisi_hba->debugfs_port_reg[p])
+ goto fail_port;
+ }
+
+ /* Alloc buffer for cq */
+ sz = hisi_hba->hw->complete_hdr_size * HISI_SAS_QUEUE_SLOTS;
+ for (c = 0; c < hisi_hba->queue_count; c++) {
+ hisi_hba->debugfs_complete_hdr[c] =
+ devm_kmalloc(dev, sz, GFP_KERNEL);
+
+ if (!hisi_hba->debugfs_complete_hdr[c])
+ goto fail_cq;
+ }
+
+ /* Alloc buffer for dq */
+ sz = hisi_hba->hw->complete_hdr_size * HISI_SAS_QUEUE_SLOTS;
+ for (d = 0; d < hisi_hba->queue_count; d++) {
+ hisi_hba->debugfs_cmd_hdr[d] =
+ devm_kmalloc(dev, sz, GFP_KERNEL);
+
+ if (!hisi_hba->debugfs_cmd_hdr[d])
+ goto fail_iost_dq;
+ }
+
+ /* Alloc buffer for iost */
+ sz = max_command_entries * sizeof(struct hisi_sas_iost);
+
+ hisi_hba->debugfs_iost = devm_kmalloc(dev, sz, GFP_KERNEL);
+ if (!hisi_hba->debugfs_iost)
+ goto fail_iost_dq;
+
+ /* Alloc buffer for itct */
+ /* New memory allocation must be locate before itct */
+ sz = HISI_SAS_MAX_ITCT_ENTRIES * sizeof(struct hisi_sas_itct);
+
+ hisi_hba->debugfs_itct = devm_kmalloc(dev, sz, GFP_KERNEL);
+ if (!hisi_hba->debugfs_itct)
+ goto fail_itct;
+
+ return;
+fail_itct:
+ devm_kfree(dev, hisi_hba->debugfs_iost);
+fail_iost_dq:
+ for (i = 0; i < d; i++)
+ devm_kfree(dev, hisi_hba->debugfs_cmd_hdr[i]);
+fail_cq:
+ for (i = 0; i < c; i++)
+ devm_kfree(dev, hisi_hba->debugfs_complete_hdr[i]);
+fail_port:
+ for (i = 0; i < p; i++)
+ devm_kfree(dev, hisi_hba->debugfs_port_reg[i]);
+ devm_kfree(dev, hisi_hba->debugfs_global_reg);
+fail_global:
+ debugfs_remove_recursive(hisi_hba->debugfs_dir);
+ dev_dbg(dev, "failed to init debugfs!\n");
+}
+EXPORT_SYMBOL_GPL(hisi_sas_debugfs_init);
+
+void hisi_sas_debugfs_exit(struct hisi_hba *hisi_hba)
+{
+ debugfs_remove_recursive(hisi_hba->debugfs_dir);
+}
+EXPORT_SYMBOL_GPL(hisi_sas_debugfs_exit);
+
int hisi_sas_remove(struct platform_device *pdev)
{
struct sas_ha_struct *sha = platform_get_drvdata(pdev);
@@ -2475,18 +2973,28 @@ int hisi_sas_remove(struct platform_device *pdev)
}
EXPORT_SYMBOL_GPL(hisi_sas_remove);
+bool hisi_sas_debugfs_enable;
+EXPORT_SYMBOL_GPL(hisi_sas_debugfs_enable);
+module_param_named(debugfs_enable, hisi_sas_debugfs_enable, bool, 0444);
+MODULE_PARM_DESC(hisi_sas_debugfs_enable, "Enable driver debugfs (default disabled)");
+
static __init int hisi_sas_init(void)
{
hisi_sas_stt = sas_domain_attach_transport(&hisi_sas_transport_ops);
if (!hisi_sas_stt)
return -ENOMEM;
+ if (hisi_sas_debugfs_enable)
+ hisi_sas_debugfs_dir = debugfs_create_dir("hisi_sas", NULL);
+
return 0;
}
static __exit void hisi_sas_exit(void)
{
sas_release_transport(hisi_sas_stt);
+
+ debugfs_remove(hisi_sas_debugfs_dir);
}
module_init(hisi_sas_init);
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
index c8ebff3ba559..5c4b8dff4c10 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
@@ -3542,8 +3542,8 @@ static int write_gpio_v2_hw(struct hisi_hba *hisi_hba, u8 reg_type,
return 0;
}
-static void wait_cmds_complete_timeout_v2_hw(struct hisi_hba *hisi_hba,
- int delay_ms, int timeout_ms)
+static int wait_cmds_complete_timeout_v2_hw(struct hisi_hba *hisi_hba,
+ int delay_ms, int timeout_ms)
{
struct device *dev = hisi_hba->dev;
int entries, entries_old = 0, time;
@@ -3557,7 +3557,12 @@ static void wait_cmds_complete_timeout_v2_hw(struct hisi_hba *hisi_hba,
msleep(delay_ms);
}
+ if (time >= timeout_ms)
+ return -ETIMEDOUT;
+
dev_dbg(dev, "wait commands complete %dms\n", time);
+
+ return 0;
}
static struct device_attribute *host_attrs_v2_hw[] = {
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
index c92b3822c408..4f1fe3c15278 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
@@ -186,6 +186,7 @@
#define CHL_INT0_MSK (PORT_BASE + 0x1c0)
#define CHL_INT1_MSK (PORT_BASE + 0x1c4)
#define CHL_INT2_MSK (PORT_BASE + 0x1c8)
+#define SAS_EC_INT_COAL_TIME (PORT_BASE + 0x1cc)
#define CHL_INT_COAL_EN (PORT_BASE + 0x1d0)
#define SAS_RX_TRAIN_TIMER (PORT_BASE + 0x2a4)
#define PHY_CTRL_RDY_MSK (PORT_BASE + 0x2b0)
@@ -205,6 +206,7 @@
#define ERR_CNT_DWS_LOST (PORT_BASE + 0x380)
#define ERR_CNT_RESET_PROB (PORT_BASE + 0x384)
#define ERR_CNT_INVLD_DW (PORT_BASE + 0x390)
+#define ERR_CNT_CODE_ERR (PORT_BASE + 0x394)
#define ERR_CNT_DISP_ERR (PORT_BASE + 0x398)
#define DEFAULT_ITCT_HW 2048 /* reset value, not reprogrammed */
@@ -2201,8 +2203,8 @@ static int write_gpio_v3_hw(struct hisi_hba *hisi_hba, u8 reg_type,
return 0;
}
-static void wait_cmds_complete_timeout_v3_hw(struct hisi_hba *hisi_hba,
- int delay_ms, int timeout_ms)
+static int wait_cmds_complete_timeout_v3_hw(struct hisi_hba *hisi_hba,
+ int delay_ms, int timeout_ms)
{
struct device *dev = hisi_hba->dev;
int entries, entries_old = 0, time;
@@ -2216,7 +2218,12 @@ static void wait_cmds_complete_timeout_v3_hw(struct hisi_hba *hisi_hba,
msleep(delay_ms);
}
+ if (time >= timeout_ms)
+ return -ETIMEDOUT;
+
dev_dbg(dev, "wait commands complete %dms\n", time);
+
+ return 0;
}
static ssize_t intr_conv_v3_hw_show(struct device *dev,
@@ -2332,6 +2339,159 @@ static struct device_attribute *host_attrs_v3_hw[] = {
NULL
};
+static const struct hisi_sas_debugfs_reg_lu debugfs_port_reg_lu[] = {
+ HISI_SAS_DEBUGFS_REG(PHY_CFG),
+ HISI_SAS_DEBUGFS_REG(HARD_PHY_LINKRATE),
+ HISI_SAS_DEBUGFS_REG(PROG_PHY_LINK_RATE),
+ HISI_SAS_DEBUGFS_REG(PHY_CTRL),
+ HISI_SAS_DEBUGFS_REG(SL_CFG),
+ HISI_SAS_DEBUGFS_REG(AIP_LIMIT),
+ HISI_SAS_DEBUGFS_REG(SL_CONTROL),
+ HISI_SAS_DEBUGFS_REG(RX_PRIMS_STATUS),
+ HISI_SAS_DEBUGFS_REG(TX_ID_DWORD0),
+ HISI_SAS_DEBUGFS_REG(TX_ID_DWORD1),
+ HISI_SAS_DEBUGFS_REG(TX_ID_DWORD2),
+ HISI_SAS_DEBUGFS_REG(TX_ID_DWORD3),
+ HISI_SAS_DEBUGFS_REG(TX_ID_DWORD4),
+ HISI_SAS_DEBUGFS_REG(TX_ID_DWORD5),
+ HISI_SAS_DEBUGFS_REG(TX_ID_DWORD6),
+ HISI_SAS_DEBUGFS_REG(TXID_AUTO),
+ HISI_SAS_DEBUGFS_REG(RX_IDAF_DWORD0),
+ HISI_SAS_DEBUGFS_REG(RXOP_CHECK_CFG_H),
+ HISI_SAS_DEBUGFS_REG(STP_LINK_TIMER),
+ HISI_SAS_DEBUGFS_REG(STP_LINK_TIMEOUT_STATE),
+ HISI_SAS_DEBUGFS_REG(CON_CFG_DRIVER),
+ HISI_SAS_DEBUGFS_REG(SAS_SSP_CON_TIMER_CFG),
+ HISI_SAS_DEBUGFS_REG(SAS_SMP_CON_TIMER_CFG),
+ HISI_SAS_DEBUGFS_REG(SAS_STP_CON_TIMER_CFG),
+ HISI_SAS_DEBUGFS_REG(CHL_INT0),
+ HISI_SAS_DEBUGFS_REG(CHL_INT1),
+ HISI_SAS_DEBUGFS_REG(CHL_INT2),
+ HISI_SAS_DEBUGFS_REG(CHL_INT0_MSK),
+ HISI_SAS_DEBUGFS_REG(CHL_INT1_MSK),
+ HISI_SAS_DEBUGFS_REG(CHL_INT2_MSK),
+ HISI_SAS_DEBUGFS_REG(SAS_EC_INT_COAL_TIME),
+ HISI_SAS_DEBUGFS_REG(CHL_INT_COAL_EN),
+ HISI_SAS_DEBUGFS_REG(SAS_RX_TRAIN_TIMER),
+ HISI_SAS_DEBUGFS_REG(PHY_CTRL_RDY_MSK),
+ HISI_SAS_DEBUGFS_REG(PHYCTRL_NOT_RDY_MSK),
+ HISI_SAS_DEBUGFS_REG(PHYCTRL_DWS_RESET_MSK),
+ HISI_SAS_DEBUGFS_REG(PHYCTRL_PHY_ENA_MSK),
+ HISI_SAS_DEBUGFS_REG(SL_RX_BCAST_CHK_MSK),
+ HISI_SAS_DEBUGFS_REG(PHYCTRL_OOB_RESTART_MSK),
+ HISI_SAS_DEBUGFS_REG(DMA_TX_STATUS),
+ HISI_SAS_DEBUGFS_REG(DMA_RX_STATUS),
+ HISI_SAS_DEBUGFS_REG(COARSETUNE_TIME),
+ HISI_SAS_DEBUGFS_REG(ERR_CNT_DWS_LOST),
+ HISI_SAS_DEBUGFS_REG(ERR_CNT_RESET_PROB),
+ HISI_SAS_DEBUGFS_REG(ERR_CNT_INVLD_DW),
+ HISI_SAS_DEBUGFS_REG(ERR_CNT_CODE_ERR),
+ HISI_SAS_DEBUGFS_REG(ERR_CNT_DISP_ERR),
+ {}
+};
+
+static const struct hisi_sas_debugfs_reg debugfs_port_reg = {
+ .lu = debugfs_port_reg_lu,
+ .count = 0x100,
+ .base_off = PORT_BASE,
+ .read_port_reg = hisi_sas_phy_read32,
+};
+
+static const struct hisi_sas_debugfs_reg_lu debugfs_global_reg_lu[] = {
+ HISI_SAS_DEBUGFS_REG(DLVRY_QUEUE_ENABLE),
+ HISI_SAS_DEBUGFS_REG(PHY_CONTEXT),
+ HISI_SAS_DEBUGFS_REG(PHY_STATE),
+ HISI_SAS_DEBUGFS_REG(PHY_PORT_NUM_MA),
+ HISI_SAS_DEBUGFS_REG(PHY_CONN_RATE),
+ HISI_SAS_DEBUGFS_REG(ITCT_CLR),
+ HISI_SAS_DEBUGFS_REG(IO_SATA_BROKEN_MSG_ADDR_LO),
+ HISI_SAS_DEBUGFS_REG(IO_SATA_BROKEN_MSG_ADDR_HI),
+ HISI_SAS_DEBUGFS_REG(SATA_INITI_D2H_STORE_ADDR_LO),
+ HISI_SAS_DEBUGFS_REG(SATA_INITI_D2H_STORE_ADDR_HI),
+ HISI_SAS_DEBUGFS_REG(CFG_MAX_TAG),
+ HISI_SAS_DEBUGFS_REG(HGC_SAS_TX_OPEN_FAIL_RETRY_CTRL),
+ HISI_SAS_DEBUGFS_REG(HGC_SAS_TXFAIL_RETRY_CTRL),
+ HISI_SAS_DEBUGFS_REG(HGC_GET_ITV_TIME),
+ HISI_SAS_DEBUGFS_REG(DEVICE_MSG_WORK_MODE),
+ HISI_SAS_DEBUGFS_REG(OPENA_WT_CONTI_TIME),
+ HISI_SAS_DEBUGFS_REG(I_T_NEXUS_LOSS_TIME),
+ HISI_SAS_DEBUGFS_REG(MAX_CON_TIME_LIMIT_TIME),
+ HISI_SAS_DEBUGFS_REG(BUS_INACTIVE_LIMIT_TIME),
+ HISI_SAS_DEBUGFS_REG(REJECT_TO_OPEN_LIMIT_TIME),
+ HISI_SAS_DEBUGFS_REG(CQ_INT_CONVERGE_EN),
+ HISI_SAS_DEBUGFS_REG(CFG_AGING_TIME),
+ HISI_SAS_DEBUGFS_REG(HGC_DFX_CFG2),
+ HISI_SAS_DEBUGFS_REG(CFG_ABT_SET_QUERY_IPTT),
+ HISI_SAS_DEBUGFS_REG(CFG_ABT_SET_IPTT_DONE),
+ HISI_SAS_DEBUGFS_REG(HGC_IOMB_PROC1_STATUS),
+ HISI_SAS_DEBUGFS_REG(CHNL_INT_STATUS),
+ HISI_SAS_DEBUGFS_REG(HGC_AXI_FIFO_ERR_INFO),
+ HISI_SAS_DEBUGFS_REG(INT_COAL_EN),
+ HISI_SAS_DEBUGFS_REG(OQ_INT_COAL_TIME),
+ HISI_SAS_DEBUGFS_REG(OQ_INT_COAL_CNT),
+ HISI_SAS_DEBUGFS_REG(ENT_INT_COAL_TIME),
+ HISI_SAS_DEBUGFS_REG(ENT_INT_COAL_CNT),
+ HISI_SAS_DEBUGFS_REG(OQ_INT_SRC),
+ HISI_SAS_DEBUGFS_REG(OQ_INT_SRC_MSK),
+ HISI_SAS_DEBUGFS_REG(ENT_INT_SRC1),
+ HISI_SAS_DEBUGFS_REG(ENT_INT_SRC2),
+ HISI_SAS_DEBUGFS_REG(ENT_INT_SRC3),
+ HISI_SAS_DEBUGFS_REG(ENT_INT_SRC_MSK1),
+ HISI_SAS_DEBUGFS_REG(ENT_INT_SRC_MSK2),
+ HISI_SAS_DEBUGFS_REG(ENT_INT_SRC_MSK3),
+ HISI_SAS_DEBUGFS_REG(CHNL_PHYUPDOWN_INT_MSK),
+ HISI_SAS_DEBUGFS_REG(CHNL_ENT_INT_MSK),
+ HISI_SAS_DEBUGFS_REG(HGC_COM_INT_MSK),
+ HISI_SAS_DEBUGFS_REG(SAS_ECC_INTR),
+ HISI_SAS_DEBUGFS_REG(SAS_ECC_INTR_MSK),
+ HISI_SAS_DEBUGFS_REG(HGC_ERR_STAT_EN),
+ HISI_SAS_DEBUGFS_REG(CQE_SEND_CNT),
+ HISI_SAS_DEBUGFS_REG(DLVRY_Q_0_DEPTH),
+ HISI_SAS_DEBUGFS_REG(DLVRY_Q_0_WR_PTR),
+ HISI_SAS_DEBUGFS_REG(DLVRY_Q_0_RD_PTR),
+ HISI_SAS_DEBUGFS_REG(HYPER_STREAM_ID_EN_CFG),
+ HISI_SAS_DEBUGFS_REG(OQ0_INT_SRC_MSK),
+ HISI_SAS_DEBUGFS_REG(COMPL_Q_0_DEPTH),
+ HISI_SAS_DEBUGFS_REG(COMPL_Q_0_WR_PTR),
+ HISI_SAS_DEBUGFS_REG(COMPL_Q_0_RD_PTR),
+ HISI_SAS_DEBUGFS_REG(AWQOS_AWCACHE_CFG),
+ HISI_SAS_DEBUGFS_REG(ARQOS_ARCACHE_CFG),
+ HISI_SAS_DEBUGFS_REG(HILINK_ERR_DFX),
+ HISI_SAS_DEBUGFS_REG(SAS_GPIO_CFG_0),
+ HISI_SAS_DEBUGFS_REG(SAS_GPIO_CFG_1),
+ HISI_SAS_DEBUGFS_REG(SAS_GPIO_TX_0_1),
+ HISI_SAS_DEBUGFS_REG(SAS_CFG_DRIVE_VLD),
+ {}
+};
+
+static const struct hisi_sas_debugfs_reg debugfs_global_reg = {
+ .lu = debugfs_global_reg_lu,
+ .count = 0x800,
+ .read_global_reg = hisi_sas_read32,
+};
+
+static void debugfs_snapshot_prepare_v3_hw(struct hisi_hba *hisi_hba)
+{
+ struct device *dev = hisi_hba->dev;
+
+ set_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags);
+
+ hisi_sas_write32(hisi_hba, DLVRY_QUEUE_ENABLE, 0);
+
+ if (wait_cmds_complete_timeout_v3_hw(hisi_hba, 100, 5000) == -ETIMEDOUT)
+ dev_dbg(dev, "Wait commands complete timeout!\n");
+
+ hisi_sas_kill_tasklets(hisi_hba);
+}
+
+static void debugfs_snapshot_restore_v3_hw(struct hisi_hba *hisi_hba)
+{
+ hisi_sas_write32(hisi_hba, DLVRY_QUEUE_ENABLE,
+ (u32)((1ULL << hisi_hba->queue_count) - 1));
+
+ clear_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags);
+}
+
static struct scsi_host_template sht_v3_hw = {
.name = DRV_NAME,
.module = THIS_MODULE,
@@ -2380,6 +2540,10 @@ static const struct hisi_sas_hw hisi_sas_v3_hw = {
.get_events = phy_get_events_v3_hw,
.write_gpio = write_gpio_v3_hw,
.wait_cmds_complete_timeout = wait_cmds_complete_timeout_v3_hw,
+ .debugfs_reg_global = &debugfs_global_reg,
+ .debugfs_reg_port = &debugfs_port_reg,
+ .snapshot_prepare = debugfs_snapshot_prepare_v3_hw,
+ .snapshot_restore = debugfs_snapshot_restore_v3_hw,
};
static struct Scsi_Host *
@@ -2397,6 +2561,7 @@ hisi_sas_shost_alloc_pci(struct pci_dev *pdev)
hisi_hba = shost_priv(shost);
INIT_WORK(&hisi_hba->rst_work, hisi_sas_rst_work_handler);
+ INIT_WORK(&hisi_hba->debugfs_work, hisi_sas_debugfs_work_handler);
hisi_hba->hw = &hisi_sas_v3_hw;
hisi_hba->pci_dev = pdev;
hisi_hba->dev = dev;
@@ -2513,6 +2678,9 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
scsi_host_set_prot(hisi_hba->shost, prot_mask);
}
+ if (hisi_sas_debugfs_enable)
+ hisi_sas_debugfs_init(hisi_hba);
+
rc = scsi_add_host(shost, dev);
if (rc)
goto err_out_ha;
@@ -2565,6 +2733,8 @@ static void hisi_sas_v3_remove(struct pci_dev *pdev)
struct hisi_hba *hisi_hba = sha->lldd_ha;
struct Scsi_Host *shost = sha->core.shost;
+ hisi_sas_debugfs_exit(hisi_hba);
+
if (timer_pending(&hisi_hba->timer))
del_timer(&hisi_hba->timer);
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index b2da8a00ec33..75dc1ec25d54 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -665,6 +665,68 @@ static int sd_sec_submit(void *data, u16 spsp, u8 secp, void *buffer,
}
#endif /* CONFIG_BLK_SED_OPAL */
+/*
+ * Look up the DIX operation based on whether the command is read or
+ * write and whether dix and dif are enabled.
+ */
+static unsigned int sd_prot_op(bool write, bool dix, bool dif)
+{
+ /* Lookup table: bit 2 (write), bit 1 (dix), bit 0 (dif) */
+ static const unsigned int ops[] = { /* wrt dix dif */
+ SCSI_PROT_NORMAL, /* 0 0 0 */
+ SCSI_PROT_READ_STRIP, /* 0 0 1 */
+ SCSI_PROT_READ_INSERT, /* 0 1 0 */
+ SCSI_PROT_READ_PASS, /* 0 1 1 */
+ SCSI_PROT_NORMAL, /* 1 0 0 */
+ SCSI_PROT_WRITE_INSERT, /* 1 0 1 */
+ SCSI_PROT_WRITE_STRIP, /* 1 1 0 */
+ SCSI_PROT_WRITE_PASS, /* 1 1 1 */
+ };
+
+ return ops[write << 2 | dix << 1 | dif];
+}
+
+/*
+ * Returns a mask of the protection flags that are valid for a given DIX
+ * operation.
+ */
+static unsigned int sd_prot_flag_mask(unsigned int prot_op)
+{
+ static const unsigned int flag_mask[] = {
+ [SCSI_PROT_NORMAL] = 0,
+
+ [SCSI_PROT_READ_STRIP] = SCSI_PROT_TRANSFER_PI |
+ SCSI_PROT_GUARD_CHECK |
+ SCSI_PROT_REF_CHECK |
+ SCSI_PROT_REF_INCREMENT,
+
+ [SCSI_PROT_READ_INSERT] = SCSI_PROT_REF_INCREMENT |
+ SCSI_PROT_IP_CHECKSUM,
+
+ [SCSI_PROT_READ_PASS] = SCSI_PROT_TRANSFER_PI |
+ SCSI_PROT_GUARD_CHECK |
+ SCSI_PROT_REF_CHECK |
+ SCSI_PROT_REF_INCREMENT |
+ SCSI_PROT_IP_CHECKSUM,
+
+ [SCSI_PROT_WRITE_INSERT] = SCSI_PROT_TRANSFER_PI |
+ SCSI_PROT_REF_INCREMENT,
+
+ [SCSI_PROT_WRITE_STRIP] = SCSI_PROT_GUARD_CHECK |
+ SCSI_PROT_REF_CHECK |
+ SCSI_PROT_REF_INCREMENT |
+ SCSI_PROT_IP_CHECKSUM,
+
+ [SCSI_PROT_WRITE_PASS] = SCSI_PROT_TRANSFER_PI |
+ SCSI_PROT_GUARD_CHECK |
+ SCSI_PROT_REF_CHECK |
+ SCSI_PROT_REF_INCREMENT |
+ SCSI_PROT_IP_CHECKSUM,
+ };
+
+ return flag_mask[prot_op];
+}
+
static unsigned char sd_setup_protect_cmnd(struct scsi_cmnd *scmd,
unsigned int dix, unsigned int dif)
{
diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h
index 7f43e6839bce..1080c85d97f8 100644
--- a/drivers/scsi/sd.h
+++ b/drivers/scsi/sd.h
@@ -188,68 +188,6 @@ static inline sector_t sectors_to_logical(struct scsi_device *sdev, sector_t sec
return sector >> (ilog2(sdev->sector_size) - 9);
}
-/*
- * Look up the DIX operation based on whether the command is read or
- * write and whether dix and dif are enabled.
- */
-static inline unsigned int sd_prot_op(bool write, bool dix, bool dif)
-{
- /* Lookup table: bit 2 (write), bit 1 (dix), bit 0 (dif) */
- const unsigned int ops[] = { /* wrt dix dif */
- SCSI_PROT_NORMAL, /* 0 0 0 */
- SCSI_PROT_READ_STRIP, /* 0 0 1 */
- SCSI_PROT_READ_INSERT, /* 0 1 0 */
- SCSI_PROT_READ_PASS, /* 0 1 1 */
- SCSI_PROT_NORMAL, /* 1 0 0 */
- SCSI_PROT_WRITE_INSERT, /* 1 0 1 */
- SCSI_PROT_WRITE_STRIP, /* 1 1 0 */
- SCSI_PROT_WRITE_PASS, /* 1 1 1 */
- };
-
- return ops[write << 2 | dix << 1 | dif];
-}
-
-/*
- * Returns a mask of the protection flags that are valid for a given DIX
- * operation.
- */
-static inline unsigned int sd_prot_flag_mask(unsigned int prot_op)
-{
- const unsigned int flag_mask[] = {
- [SCSI_PROT_NORMAL] = 0,
-
- [SCSI_PROT_READ_STRIP] = SCSI_PROT_TRANSFER_PI |
- SCSI_PROT_GUARD_CHECK |
- SCSI_PROT_REF_CHECK |
- SCSI_PROT_REF_INCREMENT,
-
- [SCSI_PROT_READ_INSERT] = SCSI_PROT_REF_INCREMENT |
- SCSI_PROT_IP_CHECKSUM,
-
- [SCSI_PROT_READ_PASS] = SCSI_PROT_TRANSFER_PI |
- SCSI_PROT_GUARD_CHECK |
- SCSI_PROT_REF_CHECK |
- SCSI_PROT_REF_INCREMENT |
- SCSI_PROT_IP_CHECKSUM,
-
- [SCSI_PROT_WRITE_INSERT] = SCSI_PROT_TRANSFER_PI |
- SCSI_PROT_REF_INCREMENT,
-
- [SCSI_PROT_WRITE_STRIP] = SCSI_PROT_GUARD_CHECK |
- SCSI_PROT_REF_CHECK |
- SCSI_PROT_REF_INCREMENT |
- SCSI_PROT_IP_CHECKSUM,
-
- [SCSI_PROT_WRITE_PASS] = SCSI_PROT_TRANSFER_PI |
- SCSI_PROT_GUARD_CHECK |
- SCSI_PROT_REF_CHECK |
- SCSI_PROT_REF_INCREMENT |
- SCSI_PROT_IP_CHECKSUM,
- };
-
- return flag_mask[prot_op];
-}
-
#ifdef CONFIG_BLK_DEV_INTEGRITY
extern void sd_dif_config_host(struct scsi_disk *);