git: cb1a0aab4f3c - main - sys/dev/arcmsr: Update Areca RAID driver to version 1.50.00.06.
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 06 Sep 2023 08:13:37 UTC
The branch main has been updated by delphij:
URL: https://cgit.FreeBSD.org/src/commit/?id=cb1a0aab4f3ca169509ab86a67a4630e72790869
commit cb1a0aab4f3ca169509ab86a67a4630e72790869
Author: 黃清隆 <ching2048@areca.com.tw>
AuthorDate: 2023-09-06 07:59:22 +0000
Commit: Xin LI <delphij@FreeBSD.org>
CommitDate: 2023-09-06 08:11:55 +0000
sys/dev/arcmsr: Update Areca RAID driver to version 1.50.00.06.
- Suppressed a harmless warning message, "arcmsr_dr_handle: target=f,
lun=0, GONE!!!," which could appear a few seconds after UEFI system
boot due to the boot volume UEFI initialization.
- Corrected various typing errors.
- Refactored arcmsr_initialize() to improve code readability.
- Added support for device IDs 1883 and 1886 controllers.
- Introduced support for controllers requiring host memory for the
RAID 5 and 6 XOR engines.
Many thanks to Areca for continuing to support FreeBSD.
MFC after: 3 days
---
sys/dev/arcmsr/arcmsr.c | 693 ++++++++++++++++++++++++++++++++----------------
sys/dev/arcmsr/arcmsr.h | 51 +++-
2 files changed, 507 insertions(+), 237 deletions(-)
diff --git a/sys/dev/arcmsr/arcmsr.c b/sys/dev/arcmsr/arcmsr.c
index 9dd3142d1933..ea37da30db93 100644
--- a/sys/dev/arcmsr/arcmsr.c
+++ b/sys/dev/arcmsr/arcmsr.c
@@ -88,6 +88,8 @@
** 1.50.00.03 05/04/2021 Ching Huang Fixed doorbell status arrived late on ARC-1886
** 1.50.00.04 12/08/2021 Ching Huang Fixed boot up hung under ARC-1886 with no volume created
** 1.50.00.05 03/23/2023 Ching Huang Fixed reading buffer empty length error
+** 1.50.00.06 08/07/2023 Ching Huang Add support adapter using system memory as XOR buffer,
+** Add support device ID 1883,1886
******************************************************************************************
*/
@@ -143,7 +145,7 @@
#define arcmsr_callout_init(a) callout_init(a, /*mpsafe*/1);
-#define ARCMSR_DRIVER_VERSION "arcmsr version 1.50.00.05 2023-03-23"
+#define ARCMSR_DRIVER_VERSION "arcmsr version 1.50.00.06 2023-08-07"
#include <dev/arcmsr/arcmsr.h>
/*
**************************************************************************
@@ -1071,7 +1073,7 @@ static void arcmsr_build_srb(struct CommandControlBlock *srb,
*/
static void arcmsr_post_srb(struct AdapterControlBlock *acb, struct CommandControlBlock *srb)
{
- u_int32_t cdb_phyaddr_low = (u_int32_t) srb->cdb_phyaddr_low;
+ u_int32_t cdb_phyaddr_low = (u_int32_t) srb->cdb_phyaddr;
struct ARCMSR_CDB *arcmsr_cdb = (struct ARCMSR_CDB *)&srb->arcmsr_cdb;
bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, (srb->srb_flags & SRB_FLAG_WRITE) ? BUS_DMASYNC_POSTWRITE:BUS_DMASYNC_POSTREAD);
@@ -1131,10 +1133,10 @@ static void arcmsr_post_srb(struct AdapterControlBlock *acb, struct CommandContr
ARCMSR_LOCK_ACQUIRE(&acb->postDone_lock);
postq_index = phbdmu->postq_index;
pinbound_srb = (struct InBound_SRB *)&phbdmu->post_qbuffer[postq_index & 0xFF];
- pinbound_srb->addressHigh = srb->cdb_phyaddr_high;
- pinbound_srb->addressLow = srb->cdb_phyaddr_low;
+ pinbound_srb->addressHigh = (u_int32_t)((srb->cdb_phyaddr >> 16) >> 16);
+ pinbound_srb->addressLow = (u_int32_t)srb->cdb_phyaddr;
pinbound_srb->length = srb->arc_cdb_size >> 2;
- arcmsr_cdb->Context = srb->cdb_phyaddr_low;
+ arcmsr_cdb->Context = (u_int32_t)srb->cdb_phyaddr;
if (postq_index & 0x4000) {
index_stripped = postq_index & 0xFF;
index_stripped += 1;
@@ -1742,7 +1744,7 @@ static void arcmsr_dr_handle(struct AdapterControlBlock *acb) {
devicemap = offsetof(struct HBA_MessageUnit, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
for (target = 0; target < 4; target++)
{
- deviceMapCurrent[target]=bus_space_read_4(acb->btag[0], acb->bhandle[0], devicemap);
+ deviceMapCurrent[target]=bus_space_read_4(acb->btag[0], acb->bhandle[0], devicemap);
devicemap += 4;
}
break;
@@ -1751,7 +1753,7 @@ static void arcmsr_dr_handle(struct AdapterControlBlock *acb) {
devicemap = offsetof(struct HBB_RWBUFFER, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
for (target = 0; target < 4; target++)
{
- deviceMapCurrent[target]=bus_space_read_4(acb->btag[1], acb->bhandle[1], devicemap);
+ deviceMapCurrent[target]=bus_space_read_4(acb->btag[1], acb->bhandle[1], devicemap);
devicemap += 4;
}
break;
@@ -1760,7 +1762,7 @@ static void arcmsr_dr_handle(struct AdapterControlBlock *acb) {
devicemap = offsetof(struct HBC_MessageUnit, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
for (target = 0; target < 4; target++)
{
- deviceMapCurrent[target]=bus_space_read_4(acb->btag[0], acb->bhandle[0], devicemap);
+ deviceMapCurrent[target]=bus_space_read_4(acb->btag[0], acb->bhandle[0], devicemap);
devicemap += 4;
}
break;
@@ -1768,7 +1770,7 @@ static void arcmsr_dr_handle(struct AdapterControlBlock *acb) {
devicemap = offsetof(struct HBD_MessageUnit, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
for (target = 0; target < 4; target++)
{
- deviceMapCurrent[target]=bus_space_read_4(acb->btag[0], acb->bhandle[0], devicemap);
+ deviceMapCurrent[target]=bus_space_read_4(acb->btag[0], acb->bhandle[0], devicemap);
devicemap += 4;
}
break;
@@ -1776,7 +1778,7 @@ static void arcmsr_dr_handle(struct AdapterControlBlock *acb) {
devicemap = offsetof(struct HBE_MessageUnit, msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
for (target = 0; target < 4; target++)
{
- deviceMapCurrent[target]=bus_space_read_4(acb->btag[0], acb->bhandle[0], devicemap);
+ deviceMapCurrent[target]=bus_space_read_4(acb->btag[0], acb->bhandle[0], devicemap);
devicemap += 4;
}
break;
@@ -1813,14 +1815,15 @@ static void arcmsr_dr_handle(struct AdapterControlBlock *acb) {
{
if(acb->device_map[target] & bit_check)
{/* unit departed */
- printf("arcmsr_dr_handle: Target=%x, lun=%x, GONE!!!\n",target,lun);
+ if (target != 0x0f)
+ printf("arcmsr_dr_handle: Target=0x%x, lun=%x, GONE!!!\n",target,lun);
arcmsr_abort_dr_ccbs(acb, target, lun);
arcmsr_rescan_lun(acb, target, lun);
acb->devstate[target][lun] = ARECA_RAID_GONE;
}
else
{/* unit arrived */
- printf("arcmsr_dr_handle: Target=%x, lun=%x, Plug-IN!!!\n",target,lun);
+ printf("arcmsr_dr_handle: Target=0x%x, lun=%x, Plug-IN!!!\n",target,lun);
arcmsr_rescan_lun(acb, target, lun);
acb->devstate[target][lun] = ARECA_RAID_GOOD;
}
@@ -3170,7 +3173,7 @@ static void arcmsr_action(struct cam_sim *psim, union ccb *pccb)
return;
}
- if(target == 16) {
+ if(target == ARCMSR_VIRTUAL_DEVICE_ID) {
/* virtual device for iop message transfer */
arcmsr_handle_virtual_command(acb, pccb);
return;
@@ -3216,7 +3219,9 @@ static void arcmsr_action(struct cam_sim *psim, union ccb *pccb)
else
cpi->base_transfer_speed = 300000;
if((acb->vendor_device_id == PCIDevVenIDARC1880) ||
+ (acb->vendor_device_id == PCIDevVenIDARC1883) ||
(acb->vendor_device_id == PCIDevVenIDARC1884) ||
+ (acb->vendor_device_id == PCIDevVenIDARC1886) ||
(acb->vendor_device_id == PCIDevVenIDARC1680) ||
(acb->vendor_device_id == PCIDevVenIDARC1214))
{
@@ -3282,7 +3287,7 @@ static void arcmsr_action(struct cam_sim *psim, union ccb *pccb)
case XPT_GET_TRAN_SETTINGS: {
struct ccb_trans_settings *cts;
- if(pccb->ccb_h.target_id == 16) {
+ if(pccb->ccb_h.target_id == ARCMSR_VIRTUAL_DEVICE_ID) {
pccb->ccb_h.status |= CAM_FUNC_NOTAVAIL;
xpt_done(pccb);
break;
@@ -3299,7 +3304,9 @@ static void arcmsr_action(struct cam_sim *psim, union ccb *pccb)
cts->protocol = PROTO_SCSI;
if((acb->vendor_device_id == PCIDevVenIDARC1880) ||
+ (acb->vendor_device_id == PCIDevVenIDARC1883) ||
(acb->vendor_device_id == PCIDevVenIDARC1884) ||
+ (acb->vendor_device_id == PCIDevVenIDARC1886) ||
(acb->vendor_device_id == PCIDevVenIDARC1680) ||
(acb->vendor_device_id == PCIDevVenIDARC1214))
{
@@ -3344,7 +3351,7 @@ static void arcmsr_action(struct cam_sim *psim, union ccb *pccb)
break;
}
case XPT_CALC_GEOMETRY:
- if(pccb->ccb_h.target_id == 16) {
+ if(pccb->ccb_h.target_id == ARCMSR_VIRTUAL_DEVICE_ID) {
pccb->ccb_h.status |= CAM_FUNC_NOTAVAIL;
xpt_done(pccb);
break;
@@ -4047,6 +4054,7 @@ static void arcmsr_get_hbf_config(struct AdapterControlBlock *acb)
acb->firm_sdram_size = acb->msgcode_rwbuffer[3]; /*firm_sdram_size, 3, 12-15*/
acb->firm_ide_channels = acb->msgcode_rwbuffer[4]; /*firm_ide_channels, 4, 16-19*/
acb->firm_cfg_version = acb->msgcode_rwbuffer[ARCMSR_FW_CFGVER_OFFSET]; /*firm_cfg_version, 25*/
+ acb->firm_PicStatus = acb->msgcode_rwbuffer[ARCMSR_FW_PICSTATUS]; /* firm_PicStatus, 30 */
if(acb->firm_numbers_queue > ARCMSR_MAX_OUTSTANDING_CMD)
acb->maxOutstanding = ARCMSR_MAX_OUTSTANDING_CMD - 1;
else
@@ -4340,6 +4348,12 @@ static u_int32_t arcmsr_iop_confirm(struct AdapterControlBlock *acb)
acb->msgcode_rwbuffer[5] = cdb_phyaddr_lo32;
acb->msgcode_rwbuffer[6] = srb_phyaddr_hi32;
acb->msgcode_rwbuffer[7] = COMPLETION_Q_POOL_SIZE;
+ if (acb->xor_mega) {
+ acb->msgcode_rwbuffer[8] = 0x555AA; //FreeBSD init 2
+ acb->msgcode_rwbuffer[9] = 0;
+ acb->msgcode_rwbuffer[10] = (uint32_t)acb->xor_sgtable_phy;
+ acb->msgcode_rwbuffer[11] = (uint32_t)((acb->xor_sgtable_phy >> 16) >> 16);
+ }
CHIP_REG_WRITE32(HBF_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_SET_CONFIG);
acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE;
CHIP_REG_WRITE32(HBF_MessageUnit, 0, iobound_doorbell, acb->out_doorbell);
@@ -4414,20 +4428,48 @@ static void arcmsr_map_free_srb(void *arg, bus_dma_segment_t *segs, int nseg, in
if((acb->adapter_type == ACB_ADAPTER_TYPE_C) || (acb->adapter_type == ACB_ADAPTER_TYPE_D)
|| (acb->adapter_type == ACB_ADAPTER_TYPE_E) || (acb->adapter_type == ACB_ADAPTER_TYPE_F))
{
- srb_tmp->cdb_phyaddr_low = srb_phyaddr;
- srb_tmp->cdb_phyaddr_high = (u_int32_t)((srb_phyaddr >> 16) >> 16);
+ srb_tmp->cdb_phyaddr = srb_phyaddr;
}
else
- srb_tmp->cdb_phyaddr_low = srb_phyaddr >> 5;
+ srb_tmp->cdb_phyaddr = srb_phyaddr >> 5;
srb_tmp->acb = acb;
srb_tmp->smid = i << 16;
acb->srbworkingQ[i] = acb->psrb_pool[i] = srb_tmp;
srb_phyaddr = srb_phyaddr + SRB_SIZE;
srb_tmp = (struct CommandControlBlock *)((unsigned long)srb_tmp + SRB_SIZE);
}
- if (acb->adapter_type == ACB_ADAPTER_TYPE_E)
+ srb_tmp = (struct CommandControlBlock *)(acb->uncacheptr + ARCMSR_SRBS_POOL_SIZE);
+ srb_phyaddr = (unsigned long)segs->ds_addr + ARCMSR_SRBS_POOL_SIZE;
+ switch (acb->adapter_type) {
+ case ACB_ADAPTER_TYPE_B: {
+ struct HBB_MessageUnit *phbbmu;
+
+ acb->pmu = (struct MessageUnit_UNION *)srb_tmp;
+ phbbmu = (struct HBB_MessageUnit *)acb->pmu;
+ phbbmu->hbb_doorbell = (struct HBB_DOORBELL *)acb->mem_base0;
+ phbbmu->hbb_rwbuffer = (struct HBB_RWBUFFER *)acb->mem_base1;
+ if (acb->vendor_device_id == PCIDevVenIDARC1203) {
+ phbbmu->drv2iop_doorbell = offsetof(struct HBB_DOORBELL_1203, drv2iop_doorbell);
+ phbbmu->drv2iop_doorbell_mask = offsetof(struct HBB_DOORBELL_1203, drv2iop_doorbell_mask);
+ phbbmu->iop2drv_doorbell = offsetof(struct HBB_DOORBELL_1203, iop2drv_doorbell);
+ phbbmu->iop2drv_doorbell_mask = offsetof(struct HBB_DOORBELL_1203, iop2drv_doorbell_mask);
+ } else {
+ phbbmu->drv2iop_doorbell = offsetof(struct HBB_DOORBELL, drv2iop_doorbell);
+ phbbmu->drv2iop_doorbell_mask = offsetof(struct HBB_DOORBELL, drv2iop_doorbell_mask);
+ phbbmu->iop2drv_doorbell = offsetof(struct HBB_DOORBELL, iop2drv_doorbell);
+ phbbmu->iop2drv_doorbell_mask = offsetof(struct HBB_DOORBELL, iop2drv_doorbell_mask);
+ }
+ }
+ break;
+ case ACB_ADAPTER_TYPE_D:
+ acb->pmu = (struct MessageUnit_UNION *)srb_tmp;
+ acb->pmu->muu.hbdmu.phbdmu = (struct HBD_MessageUnit *)acb->mem_base0;
+ break;
+ case ACB_ADAPTER_TYPE_E:
acb->pCompletionQ = (pCompletion_Q)srb_tmp;
- else if (acb->adapter_type == ACB_ADAPTER_TYPE_F) {
+ break;
+ case ACB_ADAPTER_TYPE_F: {
+ unsigned long host_buffer_dma;
acb->pCompletionQ = (pCompletion_Q)srb_tmp;
acb->completeQ_phys = srb_phyaddr;
memset(acb->pCompletionQ, 0xff, COMPLETION_Q_POOL_SIZE);
@@ -4435,9 +4477,62 @@ static void arcmsr_map_free_srb(void *arg, bus_dma_segment_t *segs, int nseg, in
acb->message_rbuffer = (u_int32_t *)((unsigned long)acb->message_wbuffer + 0x100);
acb->msgcode_rwbuffer = (u_int32_t *)((unsigned long)acb->message_wbuffer + 0x200);
memset((void *)acb->message_wbuffer, 0, MESG_RW_BUFFER_SIZE);
+ arcmsr_wait_firmware_ready(acb);
+ host_buffer_dma = acb->completeQ_phys + COMPLETION_Q_POOL_SIZE;
+ CHIP_REG_WRITE32(HBF_MessageUnit, 0, inbound_msgaddr0, (u_int32_t)(host_buffer_dma | 1)); /* host buffer low addr, bit0:1 all buffer active */
+ CHIP_REG_WRITE32(HBF_MessageUnit, 0, inbound_msgaddr1, (u_int32_t)((host_buffer_dma >> 16) >> 16));/* host buffer high addr */
+ CHIP_REG_WRITE32(HBF_MessageUnit, 0, iobound_doorbell, ARCMSR_HBFMU_DOORBELL_SYNC1); /* set host buffer physical address */
+ acb->firm_PicStatus = CHIP_REG_READ32(HBF_MessageUnit, 0, outbound_msgaddr1); /* get firmware spec info */
+ break;
+ }
}
acb->vir2phy_offset = (unsigned long)srb_tmp - (unsigned long)srb_phyaddr;
}
+
+static void arcmsr_map_xor_sgtable(void *arg, bus_dma_segment_t *segs, int nseg, int error)
+{
+ struct AdapterControlBlock *acb = arg;
+
+ acb->xor_sgtable_phy = (unsigned long)segs->ds_addr;
+ if ((nseg != 1) || ((u_int32_t)segs->ds_len != acb->init2cfg_size)) {
+ acb->acb_flags |= ACB_F_MAPXOR_FAILD;
+ printf("arcmsr%d: alloc xor table seg num or size not as i wish!\n", acb->pci_unit);
+ return;
+ }
+}
+
+static void arcmsr_map_xor_sg(void *arg, bus_dma_segment_t *segs, int nseg, int error)
+{
+ struct AdapterControlBlock *acb = arg;
+ int i;
+ struct HostRamBuf *pRamBuf;
+ struct XorSg *pxortable = (struct XorSg *)(acb->xortable + sizeof(struct HostRamBuf));
+
+ if (nseg != acb->xor_mega) {
+ acb->acb_flags |= ACB_F_MAPXOR_FAILD;
+ printf("arcmsr%d: alloc xor seg NUM not as i wish!\n", acb->pci_unit);
+ return;
+ }
+ for (i = 0; i < nseg; i++) {
+ if ((u_int32_t)segs->ds_len != ARCMSR_XOR_SEG_SIZE) {
+ acb->acb_flags |= ACB_F_MAPXOR_FAILD;
+ printf("arcmsr%d: alloc xor seg SIZE not as i wish!\n", acb->pci_unit);
+ return;
+ }
+ pxortable->xorPhys = (u_int64_t)segs->ds_addr;
+ pxortable->xorBufLen = (u_int64_t)segs->ds_len;
+ pxortable++;
+ segs++;
+ }
+ pRamBuf = (struct HostRamBuf *)acb->xortable;
+ pRamBuf->hrbSignature = 0x53425248; //HRBS
+ pRamBuf->hrbSize = ARCMSR_XOR_SEG_SIZE * nseg;
+ pRamBuf->hrbRes[0] = 0;
+ pRamBuf->hrbRes[1] = 0;
+ bus_dmamap_sync(acb->xortable_dmat, acb->xortable_dmamap, BUS_DMASYNC_PREREAD);
+ bus_dmamap_sync(acb->xor_dmat, acb->xor_dmamap, BUS_DMASYNC_PREWRITE);
+}
+
/*
************************************************************************
************************************************************************
@@ -4448,11 +4543,55 @@ static void arcmsr_free_resource(struct AdapterControlBlock *acb)
if(acb->ioctl_dev != NULL) {
destroy_dev(acb->ioctl_dev);
}
- bus_dmamap_unload(acb->srb_dmat, acb->srb_dmamap);
- bus_dmamap_destroy(acb->srb_dmat, acb->srb_dmamap);
- bus_dma_tag_destroy(acb->srb_dmat);
- bus_dma_tag_destroy(acb->dm_segs_dmat);
- bus_dma_tag_destroy(acb->parent_dmat);
+ if (acb->acb_flags & ACB_F_DMAMAP_SG)
+ bus_dmamap_unload(acb->xor_dmat, acb->xor_dmamap);
+ if (acb->xor_dmamap) {
+ bus_dmamem_free(acb->xor_dmat, acb->xorptr, acb->xor_dmamap);
+ }
+ if (acb->acb_flags & ACB_F_DMAMAP_SGTABLE)
+ bus_dmamap_unload(acb->xortable_dmat, acb->xortable_dmamap);
+ if (acb->xortable_dmamap) {
+ bus_dmamem_free(acb->xortable_dmat, acb->xortable, acb->xortable_dmamap);
+ }
+ if (acb->acb_flags & ACB_F_DMAMAP_SRB)
+ bus_dmamap_unload(acb->srb_dmat, acb->srb_dmamap);
+ if (acb->srb_dmamap) {
+ bus_dmamem_free(acb->srb_dmat, acb->uncacheptr, acb->srb_dmamap);
+ }
+ if (acb->srb_dmat)
+ bus_dma_tag_destroy(acb->srb_dmat);
+ if (acb->dm_segs_dmat)
+ bus_dma_tag_destroy(acb->dm_segs_dmat);
+ if (acb->parent_dmat)
+ bus_dma_tag_destroy(acb->parent_dmat);
+ switch(acb->adapter_type) {
+ case ACB_ADAPTER_TYPE_A:
+ if (acb->sys_res_arcmsr[0])
+ bus_release_resource(acb->pci_dev, SYS_RES_MEMORY, PCIR_BAR(0), acb->sys_res_arcmsr[0]);
+ break;
+ case ACB_ADAPTER_TYPE_B:
+ if (acb->sys_res_arcmsr[0])
+ bus_release_resource(acb->pci_dev, SYS_RES_MEMORY, PCIR_BAR(0), acb->sys_res_arcmsr[0]);
+ if (acb->sys_res_arcmsr[1])
+ bus_release_resource(acb->pci_dev, SYS_RES_MEMORY, PCIR_BAR(2), acb->sys_res_arcmsr[1]);
+ break;
+ case ACB_ADAPTER_TYPE_C:
+ if (acb->sys_res_arcmsr[0])
+ bus_release_resource(acb->pci_dev, SYS_RES_MEMORY, PCIR_BAR(1), acb->sys_res_arcmsr[0]);
+ break;
+ case ACB_ADAPTER_TYPE_D:
+ if (acb->sys_res_arcmsr[0])
+ bus_release_resource(acb->pci_dev, SYS_RES_MEMORY, PCIR_BAR(0), acb->sys_res_arcmsr[0]);
+ break;
+ case ACB_ADAPTER_TYPE_E:
+ if (acb->sys_res_arcmsr[0])
+ bus_release_resource(acb->pci_dev, SYS_RES_MEMORY, PCIR_BAR(1), acb->sys_res_arcmsr[0]);
+ break;
+ case ACB_ADAPTER_TYPE_F:
+ if (acb->sys_res_arcmsr[0])
+ bus_release_resource(acb->pci_dev, SYS_RES_MEMORY, PCIR_BAR(0), acb->sys_res_arcmsr[0]);
+ break;
+ }
}
/*
************************************************************************
@@ -4480,21 +4619,16 @@ static void arcmsr_mutex_destroy(struct AdapterControlBlock *acb)
************************************************************************
************************************************************************
*/
-static u_int32_t arcmsr_initialize(device_t dev)
+static int arcmsr_define_adapter_type(struct AdapterControlBlock *acb)
{
- struct AdapterControlBlock *acb = device_get_softc(dev);
- u_int16_t pci_command;
- int i, j,max_coherent_size;
- u_int32_t vendor_dev_id;
-
- vendor_dev_id = pci_get_devid(dev);
- acb->vendor_device_id = vendor_dev_id;
- acb->sub_device_id = pci_read_config(dev, PCIR_SUBDEV_0, 2);
- switch (vendor_dev_id) {
- case PCIDevVenIDARC1880:
- case PCIDevVenIDARC1882:
- case PCIDevVenIDARC1213:
- case PCIDevVenIDARC1223: {
+ int rc = 0;
+
+ switch (acb->vendor_device_id) {
+ case PCIDevVenIDARC1880:
+ case PCIDevVenIDARC1882:
+ case PCIDevVenIDARC1883:
+ case PCIDevVenIDARC1213:
+ case PCIDevVenIDARC1223: {
acb->adapter_type = ACB_ADAPTER_TYPE_C;
if ((acb->sub_device_id == ARECA_SUB_DEV_ID_1883) ||
(acb->sub_device_id == ARECA_SUB_DEV_ID_1216) ||
@@ -4502,158 +4636,78 @@ static u_int32_t arcmsr_initialize(device_t dev)
acb->adapter_bus_speed = ACB_BUS_SPEED_12G;
else
acb->adapter_bus_speed = ACB_BUS_SPEED_6G;
- max_coherent_size = ARCMSR_SRBS_POOL_SIZE;
- }
- break;
- case PCIDevVenIDARC1884:
- acb->adapter_type = ACB_ADAPTER_TYPE_E;
- acb->adapter_bus_speed = ACB_BUS_SPEED_12G;
- max_coherent_size = ARCMSR_SRBS_POOL_SIZE + COMPLETION_Q_POOL_SIZE;
- acb->completionQ_entry = COMPLETION_Q_POOL_SIZE / sizeof(struct deliver_completeQ);
- break;
- case PCIDevVenIDARC1886_:
- case PCIDevVenIDARC1886:
- acb->adapter_type = ACB_ADAPTER_TYPE_F;
- acb->adapter_bus_speed = ACB_BUS_SPEED_12G;
- max_coherent_size = ARCMSR_SRBS_POOL_SIZE + COMPLETION_Q_POOL_SIZE + MESG_RW_BUFFER_SIZE;
- acb->completionQ_entry = COMPLETION_Q_POOL_SIZE / sizeof(struct deliver_completeQ);
- break;
- case PCIDevVenIDARC1214: {
+ acb->max_coherent_size = ARCMSR_SRBS_POOL_SIZE;
+ }
+ break;
+ case PCIDevVenIDARC1884:
+ acb->adapter_type = ACB_ADAPTER_TYPE_E;
+ acb->adapter_bus_speed = ACB_BUS_SPEED_12G;
+ acb->max_coherent_size = ARCMSR_SRBS_POOL_SIZE + COMPLETION_Q_POOL_SIZE;
+ acb->completionQ_entry = COMPLETION_Q_POOL_SIZE / sizeof(struct deliver_completeQ);
+ break;
+ case PCIDevVenIDARC1886_0:
+ case PCIDevVenIDARC1886_:
+ case PCIDevVenIDARC1886:
+ acb->adapter_type = ACB_ADAPTER_TYPE_F;
+ acb->adapter_bus_speed = ACB_BUS_SPEED_12G;
+ acb->max_coherent_size = ARCMSR_SRBS_POOL_SIZE + COMPLETION_Q_POOL_SIZE + MESG_RW_BUFFER_SIZE;
+ acb->completionQ_entry = COMPLETION_Q_POOL_SIZE / sizeof(struct deliver_completeQ);
+ break;
+ case PCIDevVenIDARC1214:
+ case PCIDevVenIDARC1224: {
acb->adapter_type = ACB_ADAPTER_TYPE_D;
acb->adapter_bus_speed = ACB_BUS_SPEED_6G;
- max_coherent_size = ARCMSR_SRBS_POOL_SIZE + (sizeof(struct HBD_MessageUnit0));
- }
- break;
- case PCIDevVenIDARC1200:
- case PCIDevVenIDARC1201: {
+ acb->max_coherent_size = ARCMSR_SRBS_POOL_SIZE + (sizeof(struct HBD_MessageUnit0));
+ }
+ break;
+ case PCIDevVenIDARC1200:
+ case PCIDevVenIDARC1201: {
acb->adapter_type = ACB_ADAPTER_TYPE_B;
acb->adapter_bus_speed = ACB_BUS_SPEED_3G;
- max_coherent_size = ARCMSR_SRBS_POOL_SIZE + (sizeof(struct HBB_MessageUnit));
- }
- break;
- case PCIDevVenIDARC1203: {
+ acb->max_coherent_size = ARCMSR_SRBS_POOL_SIZE + (sizeof(struct HBB_MessageUnit));
+ }
+ break;
+ case PCIDevVenIDARC1203: {
acb->adapter_type = ACB_ADAPTER_TYPE_B;
acb->adapter_bus_speed = ACB_BUS_SPEED_6G;
- max_coherent_size = ARCMSR_SRBS_POOL_SIZE + (sizeof(struct HBB_MessageUnit));
- }
- break;
- case PCIDevVenIDARC1110:
- case PCIDevVenIDARC1120:
- case PCIDevVenIDARC1130:
- case PCIDevVenIDARC1160:
- case PCIDevVenIDARC1170:
- case PCIDevVenIDARC1210:
- case PCIDevVenIDARC1220:
- case PCIDevVenIDARC1230:
- case PCIDevVenIDARC1231:
- case PCIDevVenIDARC1260:
- case PCIDevVenIDARC1261:
- case PCIDevVenIDARC1270:
- case PCIDevVenIDARC1280:
- case PCIDevVenIDARC1212:
- case PCIDevVenIDARC1222:
- case PCIDevVenIDARC1380:
- case PCIDevVenIDARC1381:
- case PCIDevVenIDARC1680:
- case PCIDevVenIDARC1681: {
+ acb->max_coherent_size = ARCMSR_SRBS_POOL_SIZE + (sizeof(struct HBB_MessageUnit));
+ }
+ break;
+ case PCIDevVenIDARC1110:
+ case PCIDevVenIDARC1120:
+ case PCIDevVenIDARC1130:
+ case PCIDevVenIDARC1160:
+ case PCIDevVenIDARC1170:
+ case PCIDevVenIDARC1210:
+ case PCIDevVenIDARC1220:
+ case PCIDevVenIDARC1230:
+ case PCIDevVenIDARC1231:
+ case PCIDevVenIDARC1260:
+ case PCIDevVenIDARC1261:
+ case PCIDevVenIDARC1270:
+ case PCIDevVenIDARC1280:
+ case PCIDevVenIDARC1212:
+ case PCIDevVenIDARC1222:
+ case PCIDevVenIDARC1380:
+ case PCIDevVenIDARC1381:
+ case PCIDevVenIDARC1680:
+ case PCIDevVenIDARC1681: {
acb->adapter_type = ACB_ADAPTER_TYPE_A;
acb->adapter_bus_speed = ACB_BUS_SPEED_3G;
- max_coherent_size = ARCMSR_SRBS_POOL_SIZE;
- }
- break;
- default: {
+ acb->max_coherent_size = ARCMSR_SRBS_POOL_SIZE;
+ }
+ break;
+ default: {
printf("arcmsr%d:"
- " unknown RAID adapter type \n", device_get_unit(dev));
- return ENOMEM;
+ " unknown RAID adapter type \n", acb->pci_unit);
+ rc = ENOMEM;
}
}
- if(bus_dma_tag_create( /*PCI parent*/ bus_get_dma_tag(dev),
- /*alignemnt*/ 1,
- /*boundary*/ 0,
- /*lowaddr*/ BUS_SPACE_MAXADDR,
- /*highaddr*/ BUS_SPACE_MAXADDR,
- /*filter*/ NULL,
- /*filterarg*/ NULL,
- /*maxsize*/ BUS_SPACE_MAXSIZE_32BIT,
- /*nsegments*/ BUS_SPACE_UNRESTRICTED,
- /*maxsegsz*/ BUS_SPACE_MAXSIZE_32BIT,
- /*flags*/ 0,
- /*lockfunc*/ NULL,
- /*lockarg*/ NULL,
- &acb->parent_dmat) != 0)
- {
- printf("arcmsr%d: parent_dmat bus_dma_tag_create failure!\n", device_get_unit(dev));
- return ENOMEM;
- }
-
- /* Create a single tag describing a region large enough to hold all of the s/g lists we will need. */
- if(bus_dma_tag_create( /*parent_dmat*/ acb->parent_dmat,
- /*alignment*/ 1,
- /*boundary*/ 0,
-#ifdef PAE
- /*lowaddr*/ BUS_SPACE_MAXADDR_32BIT,
-#else
- /*lowaddr*/ BUS_SPACE_MAXADDR,
-#endif
- /*highaddr*/ BUS_SPACE_MAXADDR,
- /*filter*/ NULL,
- /*filterarg*/ NULL,
- /*maxsize*/ ARCMSR_MAX_SG_ENTRIES * PAGE_SIZE * ARCMSR_MAX_FREESRB_NUM,
- /*nsegments*/ ARCMSR_MAX_SG_ENTRIES,
- /*maxsegsz*/ BUS_SPACE_MAXSIZE_32BIT,
- /*flags*/ 0,
- /*lockfunc*/ busdma_lock_mutex,
- /*lockarg*/ &acb->isr_lock,
- &acb->dm_segs_dmat) != 0)
- {
- bus_dma_tag_destroy(acb->parent_dmat);
- printf("arcmsr%d: dm_segs_dmat bus_dma_tag_create failure!\n", device_get_unit(dev));
- return ENOMEM;
- }
+ return rc;
+}
- /* DMA tag for our srb structures.... Allocate the freesrb memory */
- if(bus_dma_tag_create( /*parent_dmat*/ acb->parent_dmat,
- /*alignment*/ 0x20,
- /*boundary*/ 0,
- /*lowaddr*/ BUS_SPACE_MAXADDR_32BIT,
- /*highaddr*/ BUS_SPACE_MAXADDR,
- /*filter*/ NULL,
- /*filterarg*/ NULL,
- /*maxsize*/ max_coherent_size,
- /*nsegments*/ 1,
- /*maxsegsz*/ BUS_SPACE_MAXSIZE_32BIT,
- /*flags*/ 0,
- /*lockfunc*/ NULL,
- /*lockarg*/ NULL,
- &acb->srb_dmat) != 0)
- {
- bus_dma_tag_destroy(acb->dm_segs_dmat);
- bus_dma_tag_destroy(acb->parent_dmat);
- printf("arcmsr%d: srb_dmat bus_dma_tag_create failure!\n", device_get_unit(dev));
- return ENXIO;
- }
- /* Allocation for our srbs */
- if(bus_dmamem_alloc(acb->srb_dmat, (void **)&acb->uncacheptr, BUS_DMA_WAITOK | BUS_DMA_COHERENT | BUS_DMA_ZERO, &acb->srb_dmamap) != 0) {
- bus_dma_tag_destroy(acb->srb_dmat);
- bus_dma_tag_destroy(acb->dm_segs_dmat);
- bus_dma_tag_destroy(acb->parent_dmat);
- printf("arcmsr%d: srb_dmat bus_dmamem_alloc failure!\n", device_get_unit(dev));
- return ENXIO;
- }
- /* And permanently map them */
- if(bus_dmamap_load(acb->srb_dmat, acb->srb_dmamap, acb->uncacheptr, max_coherent_size, arcmsr_map_free_srb, acb, /*flags*/0)) {
- bus_dma_tag_destroy(acb->srb_dmat);
- bus_dma_tag_destroy(acb->dm_segs_dmat);
- bus_dma_tag_destroy(acb->parent_dmat);
- printf("arcmsr%d: srb_dmat bus_dmamap_load failure!\n", device_get_unit(dev));
- return ENXIO;
- }
- pci_command = pci_read_config(dev, PCIR_COMMAND, 2);
- pci_command |= PCIM_CMD_BUSMASTEREN;
- pci_command |= PCIM_CMD_PERRESPEN;
- pci_command |= PCIM_CMD_MWRICEN;
- /* Enable Busmaster */
- pci_write_config(dev, PCIR_COMMAND, pci_command, 2);
+static int arcmsr_map_pcireg(device_t dev, struct AdapterControlBlock *acb)
+{
switch(acb->adapter_type) {
case ACB_ADAPTER_TYPE_A: {
u_int32_t rid0 = PCIR_BAR(0);
@@ -4662,18 +4716,18 @@ static u_int32_t arcmsr_initialize(device_t dev)
acb->sys_res_arcmsr[0] = bus_alloc_resource_any(dev,SYS_RES_MEMORY, &rid0, RF_ACTIVE);
if(acb->sys_res_arcmsr[0] == NULL) {
arcmsr_free_resource(acb);
- printf("arcmsr%d: bus_alloc_resource failure!\n", device_get_unit(dev));
+ printf("arcmsr%d: bus_alloc_resource failure!\n", acb->pci_unit);
return ENOMEM;
}
if(rman_get_start(acb->sys_res_arcmsr[0]) <= 0) {
arcmsr_free_resource(acb);
- printf("arcmsr%d: rman_get_start failure!\n", device_get_unit(dev));
+ printf("arcmsr%d: rman_get_start failure!\n", acb->pci_unit);
return ENXIO;
}
mem_base0 = (vm_offset_t) rman_get_virtual(acb->sys_res_arcmsr[0]);
if(mem_base0 == 0) {
arcmsr_free_resource(acb);
- printf("arcmsr%d: rman_get_virtual failure!\n", device_get_unit(dev));
+ printf("arcmsr%d: rman_get_virtual failure!\n", acb->pci_unit);
return ENXIO;
}
acb->btag[0] = rman_get_bustag(acb->sys_res_arcmsr[0]);
@@ -4683,47 +4737,33 @@ static u_int32_t arcmsr_initialize(device_t dev)
}
break;
case ACB_ADAPTER_TYPE_B: {
- struct HBB_MessageUnit *phbbmu;
- struct CommandControlBlock *freesrb;
u_int32_t rid[]={ PCIR_BAR(0), PCIR_BAR(2) };
vm_offset_t mem_base[]={0,0};
+ u_int16_t i;
+
for(i=0; i < 2; i++) {
acb->sys_res_arcmsr[i] = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid[i], RF_ACTIVE);
if(acb->sys_res_arcmsr[i] == NULL) {
arcmsr_free_resource(acb);
- printf("arcmsr%d: bus_alloc_resource %d failure!\n", device_get_unit(dev), i);
+ printf("arcmsr%d: bus_alloc_resource %d failure!\n", acb->pci_unit, i);
return ENOMEM;
}
if(rman_get_start(acb->sys_res_arcmsr[i]) <= 0) {
arcmsr_free_resource(acb);
- printf("arcmsr%d: rman_get_start %d failure!\n", device_get_unit(dev), i);
+ printf("arcmsr%d: rman_get_start %d failure!\n", acb->pci_unit, i);
return ENXIO;
}
mem_base[i] = (vm_offset_t) rman_get_virtual(acb->sys_res_arcmsr[i]);
if(mem_base[i] == 0) {
arcmsr_free_resource(acb);
- printf("arcmsr%d: rman_get_virtual %d failure!\n", device_get_unit(dev), i);
+ printf("arcmsr%d: rman_get_virtual %d failure!\n", acb->pci_unit, i);
return ENXIO;
}
acb->btag[i] = rman_get_bustag(acb->sys_res_arcmsr[i]);
acb->bhandle[i] = rman_get_bushandle(acb->sys_res_arcmsr[i]);
}
- freesrb = (struct CommandControlBlock *)acb->uncacheptr;
- acb->pmu = (struct MessageUnit_UNION *)((unsigned long)freesrb+ARCMSR_SRBS_POOL_SIZE);
- phbbmu = (struct HBB_MessageUnit *)acb->pmu;
- phbbmu->hbb_doorbell = (struct HBB_DOORBELL *)mem_base[0];
- phbbmu->hbb_rwbuffer = (struct HBB_RWBUFFER *)mem_base[1];
- if (vendor_dev_id == PCIDevVenIDARC1203) {
- phbbmu->drv2iop_doorbell = offsetof(struct HBB_DOORBELL_1203, drv2iop_doorbell);
- phbbmu->drv2iop_doorbell_mask = offsetof(struct HBB_DOORBELL_1203, drv2iop_doorbell_mask);
- phbbmu->iop2drv_doorbell = offsetof(struct HBB_DOORBELL_1203, iop2drv_doorbell);
- phbbmu->iop2drv_doorbell_mask = offsetof(struct HBB_DOORBELL_1203, iop2drv_doorbell_mask);
- } else {
- phbbmu->drv2iop_doorbell = offsetof(struct HBB_DOORBELL, drv2iop_doorbell);
- phbbmu->drv2iop_doorbell_mask = offsetof(struct HBB_DOORBELL, drv2iop_doorbell_mask);
- phbbmu->iop2drv_doorbell = offsetof(struct HBB_DOORBELL, iop2drv_doorbell);
- phbbmu->iop2drv_doorbell_mask = offsetof(struct HBB_DOORBELL, iop2drv_doorbell_mask);
- }
+ acb->mem_base0 = mem_base[0];
+ acb->mem_base1 = mem_base[1];
acb->rid[0] = rid[0];
acb->rid[1] = rid[1];
}
@@ -4735,18 +4775,18 @@ static u_int32_t arcmsr_initialize(device_t dev)
acb->sys_res_arcmsr[0] = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid0, RF_ACTIVE);
if(acb->sys_res_arcmsr[0] == NULL) {
arcmsr_free_resource(acb);
- printf("arcmsr%d: bus_alloc_resource failure!\n", device_get_unit(dev));
+ printf("arcmsr%d: bus_alloc_resource failure!\n", acb->pci_unit);
return ENOMEM;
}
if(rman_get_start(acb->sys_res_arcmsr[0]) <= 0) {
arcmsr_free_resource(acb);
- printf("arcmsr%d: rman_get_start failure!\n", device_get_unit(dev));
+ printf("arcmsr%d: rman_get_start failure!\n", acb->pci_unit);
return ENXIO;
}
mem_base0 = (vm_offset_t) rman_get_virtual(acb->sys_res_arcmsr[0]);
if(mem_base0 == 0) {
arcmsr_free_resource(acb);
- printf("arcmsr%d: rman_get_virtual failure!\n", device_get_unit(dev));
+ printf("arcmsr%d: rman_get_virtual failure!\n", acb->pci_unit);
return ENXIO;
}
acb->btag[0] = rman_get_bustag(acb->sys_res_arcmsr[0]);
@@ -4756,32 +4796,29 @@ static u_int32_t arcmsr_initialize(device_t dev)
}
break;
case ACB_ADAPTER_TYPE_D: {
- struct HBD_MessageUnit0 *phbdmu;
u_int32_t rid0 = PCIR_BAR(0);
vm_offset_t mem_base0;
acb->sys_res_arcmsr[0] = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid0, RF_ACTIVE);
if(acb->sys_res_arcmsr[0] == NULL) {
arcmsr_free_resource(acb);
- printf("arcmsr%d: bus_alloc_resource failure!\n", device_get_unit(dev));
+ printf("arcmsr%d: bus_alloc_resource failure!\n", acb->pci_unit);
return ENOMEM;
}
if(rman_get_start(acb->sys_res_arcmsr[0]) <= 0) {
arcmsr_free_resource(acb);
- printf("arcmsr%d: rman_get_start failure!\n", device_get_unit(dev));
+ printf("arcmsr%d: rman_get_start failure!\n", acb->pci_unit);
return ENXIO;
}
mem_base0 = (vm_offset_t) rman_get_virtual(acb->sys_res_arcmsr[0]);
if(mem_base0 == 0) {
arcmsr_free_resource(acb);
- printf("arcmsr%d: rman_get_virtual failure!\n", device_get_unit(dev));
+ printf("arcmsr%d: rman_get_virtual failure!\n", acb->pci_unit);
return ENXIO;
}
acb->btag[0] = rman_get_bustag(acb->sys_res_arcmsr[0]);
acb->bhandle[0] = rman_get_bushandle(acb->sys_res_arcmsr[0]);
- acb->pmu = (struct MessageUnit_UNION *)((unsigned long)acb->uncacheptr+ARCMSR_SRBS_POOL_SIZE);
- phbdmu = (struct HBD_MessageUnit0 *)acb->pmu;
- phbdmu->phbdmu = (struct HBD_MessageUnit *)mem_base0;
+ acb->mem_base0 = mem_base0;
acb->rid[0] = rid0;
}
break;
@@ -4792,18 +4829,18 @@ static u_int32_t arcmsr_initialize(device_t dev)
acb->sys_res_arcmsr[0] = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid0, RF_ACTIVE);
if(acb->sys_res_arcmsr[0] == NULL) {
arcmsr_free_resource(acb);
- printf("arcmsr%d: bus_alloc_resource failure!\n", device_get_unit(dev));
+ printf("arcmsr%d: bus_alloc_resource failure!\n", acb->pci_unit);
return ENOMEM;
}
if(rman_get_start(acb->sys_res_arcmsr[0]) <= 0) {
arcmsr_free_resource(acb);
- printf("arcmsr%d: rman_get_start failure!\n", device_get_unit(dev));
+ printf("arcmsr%d: rman_get_start failure!\n", acb->pci_unit);
return ENXIO;
}
mem_base0 = (vm_offset_t) rman_get_virtual(acb->sys_res_arcmsr[0]);
if(mem_base0 == 0) {
arcmsr_free_resource(acb);
- printf("arcmsr%d: rman_get_virtual failure!\n", device_get_unit(dev));
+ printf("arcmsr%d: rman_get_virtual failure!\n", acb->pci_unit);
return ENXIO;
}
acb->btag[0] = rman_get_bustag(acb->sys_res_arcmsr[0]);
@@ -4820,23 +4857,22 @@ static u_int32_t arcmsr_initialize(device_t dev)
case ACB_ADAPTER_TYPE_F: {
u_int32_t rid0 = PCIR_BAR(0);
vm_offset_t mem_base0;
- unsigned long host_buffer_dma;
acb->sys_res_arcmsr[0] = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid0, RF_ACTIVE);
if(acb->sys_res_arcmsr[0] == NULL) {
arcmsr_free_resource(acb);
- printf("arcmsr%d: bus_alloc_resource failure!\n", device_get_unit(dev));
+ printf("arcmsr%d: bus_alloc_resource failure!\n", acb->pci_unit);
return ENOMEM;
}
if(rman_get_start(acb->sys_res_arcmsr[0]) <= 0) {
arcmsr_free_resource(acb);
- printf("arcmsr%d: rman_get_start failure!\n", device_get_unit(dev));
+ printf("arcmsr%d: rman_get_start failure!\n", acb->pci_unit);
return ENXIO;
}
mem_base0 = (vm_offset_t) rman_get_virtual(acb->sys_res_arcmsr[0]);
if(mem_base0 == 0) {
arcmsr_free_resource(acb);
- printf("arcmsr%d: rman_get_virtual failure!\n", device_get_unit(dev));
+ printf("arcmsr%d: rman_get_virtual failure!\n", acb->pci_unit);
return ENXIO;
}
acb->btag[0] = rman_get_bustag(acb->sys_res_arcmsr[0]);
@@ -4848,17 +4884,203 @@ static u_int32_t arcmsr_initialize(device_t dev)
acb->rid[0] = rid0;
CHIP_REG_WRITE32(HBF_MessageUnit, 0, host_int_status, 0); /*clear interrupt*/
CHIP_REG_WRITE32(HBF_MessageUnit, 0, iobound_doorbell, ARCMSR_HBEMU_DOORBELL_SYNC); /* synchronize doorbell to 0 */
- arcmsr_wait_firmware_ready(acb);
- host_buffer_dma = acb->completeQ_phys + COMPLETION_Q_POOL_SIZE;
- CHIP_REG_WRITE32(HBF_MessageUnit, 0, inbound_msgaddr0, (u_int32_t)(host_buffer_dma | 1)); /* host buffer low addr, bit0:1 all buffer active */
- CHIP_REG_WRITE32(HBF_MessageUnit, 0, inbound_msgaddr1, (u_int32_t)((host_buffer_dma >> 16) >> 16));/* host buffer high addr */
- CHIP_REG_WRITE32(HBF_MessageUnit, 0, iobound_doorbell, ARCMSR_HBFMU_DOORBELL_SYNC1); /* set host buffer physical address */
}
break;
}
- if(acb->acb_flags & ACB_F_MAPFREESRB_FAILD) {
+ return (0);
+}
+
+static int arcmsr_alloc_srb(device_t dev, struct AdapterControlBlock *acb)
+{
+ int rc;
+
+ if(bus_dma_tag_create( /*PCI parent*/ bus_get_dma_tag(dev),
+ /*alignemnt*/ 1,
+ /*boundary*/ 0,
+ /*lowaddr*/ BUS_SPACE_MAXADDR,
+ /*highaddr*/ BUS_SPACE_MAXADDR,
+ /*filter*/ NULL,
+ /*filterarg*/ NULL,
+ /*maxsize*/ BUS_SPACE_MAXSIZE_32BIT,
+ /*nsegments*/ BUS_SPACE_UNRESTRICTED,
+ /*maxsegsz*/ BUS_SPACE_MAXSIZE_32BIT,
+ /*flags*/ 0,
+ /*lockfunc*/ NULL,
+ /*lockarg*/ NULL,
+ &acb->parent_dmat) != 0)
+ {
+ printf("arcmsr%d: parent_dmat bus_dma_tag_create failure!\n", acb->pci_unit);
+ return ENOMEM;
+ }
+
+ /* Create a single tag describing a region large enough to hold all of the s/g lists we will need. */
+ if(bus_dma_tag_create( /*parent_dmat*/ acb->parent_dmat,
+ /*alignment*/ 1,
+ /*boundary*/ 0,
+#ifdef PAE
+ /*lowaddr*/ BUS_SPACE_MAXADDR_32BIT,
+#else
+ /*lowaddr*/ BUS_SPACE_MAXADDR,
+#endif
+ /*highaddr*/ BUS_SPACE_MAXADDR,
+ /*filter*/ NULL,
+ /*filterarg*/ NULL,
+ /*maxsize*/ ARCMSR_MAX_SG_ENTRIES * PAGE_SIZE * ARCMSR_MAX_FREESRB_NUM,
+ /*nsegments*/ ARCMSR_MAX_SG_ENTRIES,
+ /*maxsegsz*/ BUS_SPACE_MAXSIZE_32BIT,
+ /*flags*/ 0,
+ /*lockfunc*/ busdma_lock_mutex,
+ /*lockarg*/ &acb->isr_lock,
+ &acb->dm_segs_dmat) != 0)
+ {
+ arcmsr_free_resource(acb);
+ printf("arcmsr%d: dm_segs_dmat bus_dma_tag_create failure!\n", acb->pci_unit);
+ return ENOMEM;
+ }
+
+ /* DMA tag for our srb structures.... Allocate the freesrb memory */
+ if(bus_dma_tag_create( /*parent_dmat*/ acb->parent_dmat,
+ /*alignment*/ 0x20,
+ /*boundary*/ 0,
+ /*lowaddr*/ BUS_SPACE_MAXADDR_32BIT,
+ /*highaddr*/ BUS_SPACE_MAXADDR,
+ /*filter*/ NULL,
+ /*filterarg*/ NULL,
+ /*maxsize*/ acb->max_coherent_size,
+ /*nsegments*/ 1,
+ /*maxsegsz*/ BUS_SPACE_MAXSIZE_32BIT,
+ /*flags*/ 0,
+ /*lockfunc*/ NULL,
+ /*lockarg*/ NULL,
+ &acb->srb_dmat) != 0)
+ {
+ arcmsr_free_resource(acb);
+ printf("arcmsr%d: srb_dmat bus_dma_tag_create failure!\n", acb->pci_unit);
+ return ENXIO;
+ }
+ /* Allocation for our srbs */
+ if(bus_dmamem_alloc(acb->srb_dmat, (void **)&acb->uncacheptr, ARCMSR_DMA_ALLOC_FLAG, &acb->srb_dmamap) != 0) {
+ arcmsr_free_resource(acb);
+ printf("arcmsr%d: srb_dmat bus_dmamem_alloc failure!\n", acb->pci_unit);
+ return ENXIO;
+ }
+ /* And permanently map them */
+ rc = bus_dmamap_load(acb->srb_dmat, acb->srb_dmamap, acb->uncacheptr, acb->max_coherent_size, arcmsr_map_free_srb, acb, /*flags*/0);
+ if((rc != 0) && (rc != EINPROGRESS)) {
+ arcmsr_free_resource(acb);
+ printf("arcmsr%d: srb_dmat bus_dmamap_load failure!\n", acb->pci_unit);
+ return ENXIO;
+ }
+ acb->acb_flags |= ACB_F_DMAMAP_SRB;
+ return (0);
+}
+
+static int arcmsr_alloc_xor_mem(device_t dev, struct AdapterControlBlock *acb)
+{
+ int rc, xor_ram;
+
+ xor_ram = (acb->firm_PicStatus >> 24) & 0x0f;
+ acb->xor_mega = (xor_ram - 1) * 32 + 128 + 3;
+ acb->init2cfg_size = sizeof(struct HostRamBuf) + (sizeof(struct XorSg) * acb->xor_mega);
+ /* DMA tag for XOR engine of Raid 5,6 */
+ if(bus_dma_tag_create( /*parent_dmat*/ acb->parent_dmat,
+ /*alignment*/ 0x40,
+ /*boundary*/ 0,
+ /*lowaddr*/ BUS_SPACE_MAXADDR_32BIT,
+ /*highaddr*/ BUS_SPACE_MAXADDR,
+ /*filter*/ NULL,
+ /*filterarg*/ NULL,
+ /*maxsize*/ acb->init2cfg_size,
+ /*nsegments*/ 1,
+ /*maxsegsz*/ acb->init2cfg_size,
+ /*flags*/ 0,
+ /*lockfunc*/ NULL,
+ /*lockarg*/ NULL,
+ &acb->xortable_dmat) != 0)
+ {
+ arcmsr_free_resource(acb);
+ printf("arcmsr%d: xor table bus_dma_tag_create failure!\n", acb->pci_unit);
+ return ENXIO;
+ }
+ /* Allocation for xors */
+ if(bus_dmamem_alloc(acb->xortable_dmat, (void **)&acb->xortable, ARCMSR_DMA_ALLOC_FLAG, &acb->xortable_dmamap) != 0) {
arcmsr_free_resource(acb);
- printf("arcmsr%d: map free srb failure!\n", device_get_unit(dev));
+ printf("arcmsr%d: xor table bus_dmamem_alloc failure!\n", acb->pci_unit);
+ return ENXIO;
+ }
+ /* And permanently map xor segs */
+ rc = bus_dmamap_load(acb->xortable_dmat, acb->xortable_dmamap, acb->xortable, acb->init2cfg_size, arcmsr_map_xor_sgtable, acb, /*flags*/0);
+ if((rc != 0) && (rc != EINPROGRESS)) {
+ arcmsr_free_resource(acb);
+ printf("arcmsr%d: xor table bus_dmamap_load failure!\n", acb->pci_unit);
+ return ENXIO;
+ }
+ acb->acb_flags |= ACB_F_DMAMAP_SGTABLE;
+
+ /* DMA tag for XOR engine of Raid 5,6 */
+ if(bus_dma_tag_create( /*parent_dmat*/ acb->parent_dmat,
+ /*alignment*/ 0x1000,
+ /*boundary*/ 0,
+ /*lowaddr*/ BUS_SPACE_MAXADDR_32BIT,
+ /*highaddr*/ BUS_SPACE_MAXADDR,
+ /*filter*/ NULL,
+ /*filterarg*/ NULL,
+ /*maxsize*/ (ARCMSR_XOR_SEG_SIZE * acb->xor_mega),
+ /*nsegments*/ acb->xor_mega,
+ /*maxsegsz*/ ARCMSR_XOR_SEG_SIZE,
+ /*flags*/ 0,
+ /*lockfunc*/ NULL,
+ /*lockarg*/ NULL,
+ &acb->xor_dmat) != 0)
+ {
+ arcmsr_free_resource(acb);
+ printf("arcmsr%d: xor bus_dma_tag_create failure!\n", acb->pci_unit);
+ return ENXIO;
+ }
+ /* Allocation for xors */
+ if(bus_dmamem_alloc(acb->xor_dmat, (void **)&acb->xorptr, ARCMSR_DMA_ALLOC_FLAG, &acb->xor_dmamap) != 0) {
+ arcmsr_free_resource(acb);
+ printf("arcmsr%d: xor bus_dmamem_alloc failure!\n", acb->pci_unit);
*** 247 LINES SKIPPED ***