svn commit: r321064 - in stable/11: share/man/man4 sys/dev/arcmsr
Xin LI
delphij at FreeBSD.org
Mon Jul 17 02:52:03 UTC 2017
Author: delphij
Date: Mon Jul 17 02:52:02 2017
New Revision: 321064
URL: https://svnweb.freebsd.org/changeset/base/321064
Log:
MFC r320986:
Update arcmsr(4) to 1.40.00.00 in order to add support of
ARC-1884 SATA RAID controllers.
Many thanks to Areca for continuing to support FreeBSD.
Submitted by: 黃清隆 <ching2048 areca com tw>
Modified:
stable/11/share/man/man4/arcmsr.4
stable/11/sys/dev/arcmsr/arcmsr.c
stable/11/sys/dev/arcmsr/arcmsr.h
Directory Properties:
stable/11/ (props changed)
Modified: stable/11/share/man/man4/arcmsr.4
==============================================================================
--- stable/11/share/man/man4/arcmsr.4 Mon Jul 17 00:42:13 2017 (r321063)
+++ stable/11/share/man/man4/arcmsr.4 Mon Jul 17 02:52:02 2017 (r321064)
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd December 4, 2015
+.Dd July 14, 2017
.Dt ARCMSR 4
.Os
.Sh NAME
@@ -147,6 +147,8 @@ ARC-1880
ARC-1882
.It
ARC-1883
+.It
+ARC-1884
.El
.Sh FILES
.Bl -tag -width ".Pa /dev/arcmsr?" -compact
Modified: stable/11/sys/dev/arcmsr/arcmsr.c
==============================================================================
--- stable/11/sys/dev/arcmsr/arcmsr.c Mon Jul 17 00:42:13 2017 (r321063)
+++ stable/11/sys/dev/arcmsr/arcmsr.c Mon Jul 17 02:52:02 2017 (r321064)
@@ -77,6 +77,7 @@
** 1.20.00.28 09/13/2013 Ching Huang Removed recursive mutex in arcmsr_abort_dr_ccbs
** 1.20.00.29 12/18/2013 Ching Huang Change simq allocation number, support ARC1883
** 1.30.00.00 11/30/2015 Ching Huang Added support ARC1203
+** 1.40.00.00 07/11/2017 Ching Huang Added support ARC1884
******************************************************************************************
*/
@@ -148,7 +149,7 @@ __FBSDID("$FreeBSD$");
#define arcmsr_callout_init(a) callout_init(a);
#endif
-#define ARCMSR_DRIVER_VERSION "arcmsr version 1.30.00.00 2015-11-30"
+#define ARCMSR_DRIVER_VERSION "arcmsr version 1.40.00.00 2017-07-11"
#include <dev/arcmsr/arcmsr.h>
/*
**************************************************************************
@@ -185,6 +186,8 @@ static void arcmsr_rescanLun_cb(struct cam_periph *per
static void arcmsr_polling_devmap(void *arg);
static void arcmsr_srb_timeout(void *arg);
static void arcmsr_hbd_postqueue_isr(struct AdapterControlBlock *acb);
+static void arcmsr_hbe_postqueue_isr(struct AdapterControlBlock *acb);
+void arcmsr_teardown_intr(device_t dev, struct AdapterControlBlock *acb);
#ifdef ARCMSR_DEBUG1
static void arcmsr_dump_data(struct AdapterControlBlock *acb);
#endif
@@ -376,6 +379,12 @@ static u_int32_t arcmsr_disable_allintr( struct Adapte
CHIP_REG_WRITE32(HBD_MessageUnit, 0, pcief0_int_enable, ARCMSR_HBDMU_ALL_INT_DISABLE);
}
break;
+ case ACB_ADAPTER_TYPE_E: {
+ /* disable all outbound interrupt */
+ intmask_org = CHIP_REG_READ32(HBC_MessageUnit, 0, host_int_mask) ; /* disable outbound message0 int */
+ CHIP_REG_WRITE32(HBE_MessageUnit, 0, host_int_mask, intmask_org | ARCMSR_HBEMU_ALL_INTMASKENABLE);
+ }
+ break;
}
return (intmask_org);
}
@@ -418,6 +427,13 @@ static void arcmsr_enable_allintr( struct AdapterContr
acb->outbound_int_enable = mask;
}
break;
+ case ACB_ADAPTER_TYPE_E: {
+ /* enable outbound Post Queue, outbound doorbell Interrupt */
+ mask = ~(ARCMSR_HBEMU_OUTBOUND_DOORBELL_ISR | ARCMSR_HBEMU_OUTBOUND_POSTQUEUE_ISR);
+ CHIP_REG_WRITE32(HBE_MessageUnit, 0, host_int_mask, intmask_org & mask);
+ acb->outbound_int_enable = ~(intmask_org & mask) & 0x0000000f;
+ }
+ break;
}
}
/*
@@ -503,6 +519,28 @@ static u_int8_t arcmsr_hbd_wait_msgint_ready(struct Ad
return (FALSE);
}
/*
+**********************************************************************
+**********************************************************************
+*/
+static u_int8_t arcmsr_hbe_wait_msgint_ready(struct AdapterControlBlock *acb)
+{
+ u_int32_t Index, read_doorbell;
+ u_int8_t Retries = 0x00;
+
+ do {
+ for(Index=0; Index < 100; Index++) {
+ read_doorbell = CHIP_REG_READ32(HBE_MessageUnit, 0, iobound_doorbell);
+ if((read_doorbell ^ acb->in_doorbell) & ARCMSR_HBEMU_IOP2DRV_MESSAGE_CMD_DONE) {
+ CHIP_REG_WRITE32(HBE_MessageUnit, 0, host_int_status, 0);/*clear interrupt*/
+ acb->in_doorbell = read_doorbell;
+ return TRUE;
+ }
+ UDELAY(10000);
+ }/*max 1 seconds*/
+ }while(Retries++ < 20);/*max 20 sec*/
+ return (FALSE);
+}
+/*
************************************************************************
************************************************************************
*/
@@ -576,6 +614,25 @@ static void arcmsr_flush_hbd_cache(struct AdapterContr
************************************************************************
************************************************************************
*/
+static void arcmsr_flush_hbe_cache(struct AdapterControlBlock *acb)
+{
+ int retry_count = 30;/* enlarge wait flush adapter cache time: 10 minute */
+
+ CHIP_REG_WRITE32(HBE_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_FLUSH_CACHE);
+ acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE;
+ CHIP_REG_WRITE32(HBE_MessageUnit, 0, iobound_doorbell, acb->out_doorbell);
+ do {
+ if(arcmsr_hbe_wait_msgint_ready(acb)) {
+ break;
+ } else {
+ retry_count--;
+ }
+ }while(retry_count != 0);
+}
+/*
+************************************************************************
+************************************************************************
+*/
static void arcmsr_flush_adapter_cache(struct AdapterControlBlock *acb)
{
switch (acb->adapter_type) {
@@ -595,6 +652,10 @@ static void arcmsr_flush_adapter_cache(struct AdapterC
arcmsr_flush_hbd_cache(acb);
}
break;
+ case ACB_ADAPTER_TYPE_E: {
+ arcmsr_flush_hbe_cache(acb);
+ }
+ break;
}
}
/*
@@ -715,6 +776,19 @@ static void arcmsr_abort_hbd_allcmd(struct AdapterCont
*********************************************************************
*********************************************************************
*/
+static void arcmsr_abort_hbe_allcmd(struct AdapterControlBlock *acb)
+{
+ CHIP_REG_WRITE32(HBE_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_ABORT_CMD);
+ acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE;
+ CHIP_REG_WRITE32(HBE_MessageUnit, 0, iobound_doorbell, acb->out_doorbell);
+ if(!arcmsr_hbe_wait_msgint_ready(acb)) {
+ printf("arcmsr%d: wait 'abort all outstanding command' timeout \n", acb->pci_unit);
+ }
+}
+/*
+*********************************************************************
+*********************************************************************
+*/
static void arcmsr_abort_allcmd(struct AdapterControlBlock *acb)
{
switch (acb->adapter_type) {
@@ -734,6 +808,10 @@ static void arcmsr_abort_allcmd(struct AdapterControlB
arcmsr_abort_hbd_allcmd(acb);
}
break;
+ case ACB_ADAPTER_TYPE_E: {
+ arcmsr_abort_hbe_allcmd(acb);
+ }
+ break;
}
}
/*
@@ -836,6 +914,9 @@ static void arcmsr_drain_donequeue(struct AdapterContr
case ACB_ADAPTER_TYPE_D:
srb = (struct CommandControlBlock *)(acb->vir2phy_offset+(flag_srb & 0xFFFFFFE0)); /*frame must be 32 bytes aligned*/
break;
+ case ACB_ADAPTER_TYPE_E:
+ srb = acb->psrb_pool[flag_srb];
+ break;
case ACB_ADAPTER_TYPE_A:
case ACB_ADAPTER_TYPE_B:
default:
@@ -938,6 +1019,10 @@ static void arcmsr_done4abort_postqueue(struct Adapter
arcmsr_hbd_postqueue_isr(acb);
}
break;
+ case ACB_ADAPTER_TYPE_E: {
+ arcmsr_hbe_postqueue_isr(acb);
+ }
+ break;
}
}
/*
@@ -1149,6 +1234,15 @@ static void arcmsr_post_srb(struct AdapterControlBlock
ARCMSR_LOCK_RELEASE(&acb->postDone_lock);
}
break;
+ case ACB_ADAPTER_TYPE_E: {
+ u_int32_t ccb_post_stamp, arc_cdb_size;
+
+ arc_cdb_size = (srb->arc_cdb_size > 0x300) ? 0x300 : srb->arc_cdb_size;
+ ccb_post_stamp = (srb->smid | ((arc_cdb_size-1) >> 6));
+ CHIP_REG_WRITE32(HBE_MessageUnit, 0, inbound_queueport_high, 0);
+ CHIP_REG_WRITE32(HBE_MessageUnit, 0, inbound_queueport_low, ccb_post_stamp);
+ }
+ break;
}
}
/*
@@ -1184,6 +1278,12 @@ static struct QBUFFER *arcmsr_get_iop_rqbuffer( struct
qbuffer = (struct QBUFFER *)&phbdmu->phbdmu->message_rbuffer;
}
break;
+ case ACB_ADAPTER_TYPE_E: {
+ struct HBE_MessageUnit *phbcmu = (struct HBE_MessageUnit *)acb->pmu;
+
+ qbuffer = (struct QBUFFER *)&phbcmu->message_rbuffer;
+ }
+ break;
}
return(qbuffer);
}
@@ -1220,6 +1320,12 @@ static struct QBUFFER *arcmsr_get_iop_wqbuffer( struct
qbuffer = (struct QBUFFER *)&phbdmu->phbdmu->message_wbuffer;
}
break;
+ case ACB_ADAPTER_TYPE_E: {
+ struct HBE_MessageUnit *phbcmu = (struct HBE_MessageUnit *)acb->pmu;
+
+ qbuffer = (struct QBUFFER *)&phbcmu->message_wbuffer;
+ }
+ break;
}
return(qbuffer);
}
@@ -1251,6 +1357,12 @@ static void arcmsr_iop_message_read(struct AdapterCont
CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_doorbell, ARCMSR_HBDMU_DRV2IOP_DATA_OUT_READ);
}
break;
+ case ACB_ADAPTER_TYPE_E: {
+ /* let IOP know data has been read */
+ acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_DATA_READ_OK;
+ CHIP_REG_WRITE32(HBE_MessageUnit, 0, iobound_doorbell, acb->out_doorbell);
+ }
+ break;
}
}
/*
@@ -1293,6 +1405,15 @@ static void arcmsr_iop_message_wrote(struct AdapterCon
CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_doorbell, ARCMSR_HBDMU_DRV2IOP_DATA_IN_READY);
}
break;
+ case ACB_ADAPTER_TYPE_E: {
+ /*
+ ** push inbound doorbell tell iop, driver data write ok
+ ** and wait reply on next hwinterrupt for next Qbuffer post
+ */
+ acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_DATA_WRITE_OK;
+ CHIP_REG_WRITE32(HBE_MessageUnit, 0, iobound_doorbell, acb->out_doorbell);
+ }
+ break;
}
}
/*
@@ -1352,6 +1473,20 @@ static void arcmsr_stop_hbd_bgrb(struct AdapterControl
************************************************************************
************************************************************************
*/
+static void arcmsr_stop_hbe_bgrb(struct AdapterControlBlock *acb)
+{
+ acb->acb_flags &= ~ACB_F_MSG_START_BGRB;
+ CHIP_REG_WRITE32(HBE_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_STOP_BGRB);
+ acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE;
+ CHIP_REG_WRITE32(HBE_MessageUnit, 0, iobound_doorbell, acb->out_doorbell);
+ if(!arcmsr_hbe_wait_msgint_ready(acb)) {
+ printf("arcmsr%d: wait 'stop adapter background rebulid' timeout \n", acb->pci_unit);
+ }
+}
+/*
+************************************************************************
+************************************************************************
+*/
static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb)
{
switch (acb->adapter_type) {
@@ -1371,6 +1506,10 @@ static void arcmsr_stop_adapter_bgrb(struct AdapterCon
arcmsr_stop_hbd_bgrb(acb);
}
break;
+ case ACB_ADAPTER_TYPE_E: {
+ arcmsr_stop_hbe_bgrb(acb);
+ }
+ break;
}
}
/*
@@ -1446,7 +1585,8 @@ static u_int32_t arcmsr_Read_iop_rqbuffer_data(struct
u_int8_t *iop_data;
u_int32_t iop_len;
- if(acb->adapter_type & (ACB_ADAPTER_TYPE_C | ACB_ADAPTER_TYPE_D)) {
+ if((acb->adapter_type == ACB_ADAPTER_TYPE_C) || (acb->adapter_type == ACB_ADAPTER_TYPE_D) ||
+ (acb->adapter_type == ACB_ADAPTER_TYPE_E)) {
return(arcmsr_Read_iop_rqbuffer_data_D(acb, prbuffer));
}
iop_data = (u_int8_t *)prbuffer->data;
@@ -1541,7 +1681,8 @@ static void arcmsr_Write_data_2iop_wqbuffer(struct Ada
u_int8_t *iop_data;
int32_t allxfer_len=0;
- if(acb->adapter_type & (ACB_ADAPTER_TYPE_C | ACB_ADAPTER_TYPE_D)) {
+ if((acb->adapter_type == ACB_ADAPTER_TYPE_C) || (acb->adapter_type == ACB_ADAPTER_TYPE_D) ||
+ (acb->adapter_type == ACB_ADAPTER_TYPE_E)) {
arcmsr_Write_data_2iop_wqbuffer_D(acb);
return;
}
@@ -1694,6 +1835,14 @@ static void arcmsr_dr_handle(struct AdapterControlBloc
devicemap += 4;
}
break;
+ case ACB_ADAPTER_TYPE_E:
+ 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);
+ devicemap += 4;
+ }
+ break;
}
if(acb->acb_flags & ACB_F_BUS_HANG_ON)
@@ -1792,6 +1941,18 @@ static void arcmsr_hbd_message_isr(struct AdapterContr
**************************************************************************
**************************************************************************
*/
+static void arcmsr_hbe_message_isr(struct AdapterControlBlock *acb) {
+ u_int32_t outbound_message;
+
+ CHIP_REG_WRITE32(HBE_MessageUnit, 0, host_int_status, 0);
+ outbound_message = CHIP_REG_READ32(HBE_MessageUnit, 0, msgcode_rwbuffer[0]);
+ if (outbound_message == ARCMSR_SIGNATURE_GET_CONFIG)
+ arcmsr_dr_handle( acb );
+}
+/*
+**************************************************************************
+**************************************************************************
+*/
static void arcmsr_hba_doorbell_isr(struct AdapterControlBlock *acb)
{
u_int32_t doorbell_status;
@@ -1876,6 +2037,35 @@ static void arcmsr_hbd_doorbell_isr(struct AdapterCont
**************************************************************************
**************************************************************************
*/
+static void arcmsr_hbe_doorbell_isr(struct AdapterControlBlock *acb)
+{
+ u_int32_t doorbell_status, in_doorbell;
+
+ /*
+ *******************************************************************
+ ** Maybe here we need to check wrqbuffer_lock is lock or not
+ ** DOORBELL: din! don!
+ ** check if there are any mail need to pack from firmware
+ *******************************************************************
+ */
+ in_doorbell = CHIP_REG_READ32(HBE_MessageUnit, 0, iobound_doorbell);
+ CHIP_REG_WRITE32(HBE_MessageUnit, 0, host_int_status, 0); /* clear doorbell interrupt */
+ doorbell_status = in_doorbell ^ acb->in_doorbell;
+ if(doorbell_status & ARCMSR_HBEMU_IOP2DRV_DATA_WRITE_OK) {
+ arcmsr_iop2drv_data_wrote_handle(acb);
+ }
+ if(doorbell_status & ARCMSR_HBEMU_IOP2DRV_DATA_READ_OK) {
+ arcmsr_iop2drv_data_read_handle(acb);
+ }
+ if(doorbell_status & ARCMSR_HBEMU_IOP2DRV_MESSAGE_CMD_DONE) {
+ arcmsr_hbe_message_isr(acb); /* messenger of "driver to iop commands" */
+ }
+ acb->in_doorbell = in_doorbell;
+}
+/*
+**************************************************************************
+**************************************************************************
+*/
static void arcmsr_hba_postqueue_isr(struct AdapterControlBlock *acb)
{
u_int32_t flag_srb;
@@ -2013,6 +2203,34 @@ static void arcmsr_hbd_postqueue_isr(struct AdapterCon
CHIP_REG_READ32(HBD_MessageUnit, 0, outboundlist_interrupt_cause); /*Dummy ioread32 to force pci flush */
}
/*
+**************************************************************************
+**************************************************************************
+*/
+static void arcmsr_hbe_postqueue_isr(struct AdapterControlBlock *acb)
+{
+ u_int16_t error;
+ uint32_t doneq_index;
+ uint16_t cmdSMID;
+
+ /*
+ *****************************************************************************
+ ** areca cdb command done
+ *****************************************************************************
+ */
+ bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+ doneq_index = acb->doneq_index;
+ while ((CHIP_REG_READ32(HBE_MessageUnit, 0, reply_post_producer_index) & 0xFFFF) != doneq_index) {
+ cmdSMID = acb->pCompletionQ[doneq_index].cmdSMID;
+ error = (acb->pCompletionQ[doneq_index].cmdFlag & ARCMSR_SRBREPLY_FLAG_ERROR_MODE1) ? TRUE : FALSE;
+ arcmsr_drain_donequeue(acb, (u_int32_t)cmdSMID, error);
+ doneq_index++;
+ if (doneq_index >= acb->completionQ_entry)
+ doneq_index = 0;
+ }
+ acb->doneq_index = doneq_index;
+ CHIP_REG_WRITE32(HBE_MessageUnit, 0, reply_post_consumer_index, doneq_index);
+}
+/*
**********************************************************************
**********************************************************************
*/
@@ -2143,6 +2361,37 @@ static void arcmsr_handle_hbd_isr( struct AdapterContr
// CHIP_REG_READ32(HBD_MessageUnit, 0, pcief0_int_enable);
}
/*
+**********************************************************************
+**********************************************************************
+*/
+static void arcmsr_handle_hbe_isr( struct AdapterControlBlock *acb)
+{
+ u_int32_t host_interrupt_status;
+ /*
+ *********************************************
+ ** check outbound intstatus
+ *********************************************
+ */
+ host_interrupt_status = CHIP_REG_READ32(HBE_MessageUnit, 0, host_int_status) &
+ (ARCMSR_HBEMU_OUTBOUND_POSTQUEUE_ISR |
+ ARCMSR_HBEMU_OUTBOUND_DOORBELL_ISR);
+ if(!host_interrupt_status) {
+ /*it must be share irq*/
+ return;
+ }
+ do {
+ /* MU doorbell interrupts*/
+ if(host_interrupt_status & ARCMSR_HBEMU_OUTBOUND_DOORBELL_ISR) {
+ arcmsr_hbe_doorbell_isr(acb);
+ }
+ /* MU post queue interrupts*/
+ if(host_interrupt_status & ARCMSR_HBEMU_OUTBOUND_POSTQUEUE_ISR) {
+ arcmsr_hbe_postqueue_isr(acb);
+ }
+ host_interrupt_status = CHIP_REG_READ32(HBE_MessageUnit, 0, host_int_status);
+ } while (host_interrupt_status & (ARCMSR_HBEMU_OUTBOUND_POSTQUEUE_ISR | ARCMSR_HBEMU_OUTBOUND_DOORBELL_ISR));
+}
+/*
******************************************************************************
******************************************************************************
*/
@@ -2161,6 +2410,9 @@ static void arcmsr_interrupt(struct AdapterControlBloc
case ACB_ADAPTER_TYPE_D:
arcmsr_handle_hbd_isr(acb);
break;
+ case ACB_ADAPTER_TYPE_E:
+ arcmsr_handle_hbe_isr(acb);
+ break;
default:
printf("arcmsr%d: interrupt service,"
" unknown adapter type =%d\n", acb->pci_unit, acb->adapter_type);
@@ -2205,6 +2457,12 @@ static void arcmsr_polling_devmap(void *arg)
case ACB_ADAPTER_TYPE_D:
CHIP_REG_WRITE32(HBD_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG);
break;
+
+ case ACB_ADAPTER_TYPE_E:
+ CHIP_REG_WRITE32(HBE_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG);
+ acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE;
+ CHIP_REG_WRITE32(HBE_MessageUnit, 0, iobound_doorbell, acb->out_doorbell);
+ break;
}
if((acb->acb_flags & ACB_F_SCSISTOPADAPTER) == 0)
@@ -2907,6 +3165,7 @@ static void arcmsr_action(struct cam_sim *psim, union
else
cpi->base_transfer_speed = 300000;
if((acb->vendor_device_id == PCIDevVenIDARC1880) ||
+ (acb->vendor_device_id == PCIDevVenIDARC1884) ||
(acb->vendor_device_id == PCIDevVenIDARC1680) ||
(acb->vendor_device_id == PCIDevVenIDARC1214))
{
@@ -2991,6 +3250,7 @@ static void arcmsr_action(struct cam_sim *psim, union
cts->protocol = PROTO_SCSI;
if((acb->vendor_device_id == PCIDevVenIDARC1880) ||
+ (acb->vendor_device_id == PCIDevVenIDARC1884) ||
(acb->vendor_device_id == PCIDevVenIDARC1680) ||
(acb->vendor_device_id == PCIDevVenIDARC1214))
{
@@ -3150,6 +3410,20 @@ static void arcmsr_start_hbd_bgrb(struct AdapterContro
**********************************************************************
**********************************************************************
*/
+static void arcmsr_start_hbe_bgrb(struct AdapterControlBlock *acb)
+{
+ acb->acb_flags |= ACB_F_MSG_START_BGRB;
+ CHIP_REG_WRITE32(HBE_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_START_BGRB);
+ acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE;
+ CHIP_REG_WRITE32(HBE_MessageUnit, 0, iobound_doorbell, acb->out_doorbell);
+ if(!arcmsr_hbe_wait_msgint_ready(acb)) {
+ printf("arcmsr%d: wait 'start adapter background rebulid' timeout \n", acb->pci_unit);
+ }
+}
+/*
+**********************************************************************
+**********************************************************************
+*/
static void arcmsr_start_adapter_bgrb(struct AdapterControlBlock *acb)
{
switch (acb->adapter_type) {
@@ -3165,6 +3439,9 @@ static void arcmsr_start_adapter_bgrb(struct AdapterCo
case ACB_ADAPTER_TYPE_D:
arcmsr_start_hbd_bgrb(acb);
break;
+ case ACB_ADAPTER_TYPE_E:
+ arcmsr_start_hbe_bgrb(acb);
+ break;
}
}
/*
@@ -3388,8 +3665,63 @@ polling_ccb_retry:
}
/*
**********************************************************************
+**
**********************************************************************
*/
+static void arcmsr_polling_hbe_srbdone(struct AdapterControlBlock *acb, struct CommandControlBlock *poll_srb)
+{
+ struct CommandControlBlock *srb;
+ u_int32_t poll_srb_done=0, poll_count=0, doneq_index;
+ u_int16_t error, cmdSMID;
+
+polling_ccb_retry:
+ poll_count++;
+ bus_dmamap_sync(acb->srb_dmat, acb->srb_dmamap, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
+ while(1) {
+ doneq_index = acb->doneq_index;
+ if((CHIP_REG_READ32(HBE_MessageUnit, 0, reply_post_producer_index) & 0xFFFF) == doneq_index) {
+ if(poll_srb_done) {
+ break;/*chip FIFO no ccb for completion already*/
+ } else {
+ UDELAY(25000);
+ if ((poll_count > 100) && (poll_srb != NULL)) {
+ break;
+ }
+ if (acb->srboutstandingcount == 0) {
+ break;
+ }
+ goto polling_ccb_retry;
+ }
+ }
+ cmdSMID = acb->pCompletionQ[doneq_index].cmdSMID;
+ doneq_index++;
+ if (doneq_index >= acb->completionQ_entry)
+ doneq_index = 0;
+ acb->doneq_index = doneq_index;
+ srb = acb->psrb_pool[cmdSMID];
+ error = (acb->pCompletionQ[doneq_index].cmdFlag & ARCMSR_SRBREPLY_FLAG_ERROR_MODE1) ? TRUE : FALSE;
+ if (poll_srb != NULL)
+ poll_srb_done = (srb == poll_srb) ? 1:0;
+ if((srb->acb != acb) || (srb->srb_state != ARCMSR_SRB_START)) {
+ if(srb->srb_state == ARCMSR_SRB_ABORTED) {
+ printf("arcmsr%d: scsi id=%d lun=%jx srb='%p'poll command abort successfully \n"
+ , acb->pci_unit, srb->pccb->ccb_h.target_id, (uintmax_t)srb->pccb->ccb_h.target_lun, srb);
+ srb->pccb->ccb_h.status |= CAM_REQ_ABORTED;
+ arcmsr_srb_complete(srb, 1);
+ continue;
+ }
+ printf("arcmsr%d: polling get an illegal srb command done srb='%p'srboutstandingcount=%d \n"
+ , acb->pci_unit, srb, acb->srboutstandingcount);
+ continue;
+ }
+ arcmsr_report_srb_state(acb, srb, error);
+ } /*drain reply FIFO*/
+ CHIP_REG_WRITE32(HBE_MessageUnit, 0, reply_post_producer_index, doneq_index);
+}
+/*
+**********************************************************************
+**********************************************************************
+*/
static void arcmsr_polling_srbdone(struct AdapterControlBlock *acb, struct CommandControlBlock *poll_srb)
{
switch (acb->adapter_type) {
@@ -3409,6 +3741,10 @@ static void arcmsr_polling_srbdone(struct AdapterContr
arcmsr_polling_hbd_srbdone(acb, poll_srb);
}
break;
+ case ACB_ADAPTER_TYPE_E: {
+ arcmsr_polling_hbe_srbdone(acb, poll_srb);
+ }
+ break;
}
}
/*
@@ -3615,6 +3951,58 @@ static void arcmsr_get_hbd_config(struct AdapterContro
**********************************************************************
**********************************************************************
*/
+static void arcmsr_get_hbe_config(struct AdapterControlBlock *acb)
+{
+ char *acb_firm_model = acb->firm_model;
+ char *acb_firm_version = acb->firm_version;
+ char *acb_device_map = acb->device_map;
+ size_t iop_firm_model = offsetof(struct HBE_MessageUnit,msgcode_rwbuffer[ARCMSR_FW_MODEL_OFFSET]); /*firm_model,15,60-67*/
+ size_t iop_firm_version = offsetof(struct HBE_MessageUnit,msgcode_rwbuffer[ARCMSR_FW_VERS_OFFSET]); /*firm_version,17,68-83*/
+ size_t iop_device_map = offsetof(struct HBE_MessageUnit,msgcode_rwbuffer[ARCMSR_FW_DEVMAP_OFFSET]);
+ int i;
+
+ CHIP_REG_WRITE32(HBE_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_GET_CONFIG);
+ acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE;
+ CHIP_REG_WRITE32(HBE_MessageUnit, 0, iobound_doorbell, acb->out_doorbell);
+ if(!arcmsr_hbe_wait_msgint_ready(acb)) {
+ printf("arcmsr%d: wait 'get adapter firmware miscellaneous data' timeout \n", acb->pci_unit);
+ }
+
+ i = 0;
+ while(i < 8) {
+ *acb_firm_model = bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_firm_model+i);
+ /* 8 bytes firm_model, 15, 60-67*/
+ acb_firm_model++;
+ i++;
+ }
+ i = 0;
+ while(i < 16) {
+ *acb_firm_version = bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_firm_version+i);
+ /* 16 bytes firm_version, 17, 68-83*/
+ acb_firm_version++;
+ i++;
+ }
+ i = 0;
+ while(i < 16) {
+ *acb_device_map = bus_space_read_1(acb->btag[0], acb->bhandle[0], iop_device_map+i);
+ acb_device_map++;
+ i++;
+ }
+ printf("Areca RAID adapter%d: %s F/W version %s \n", acb->pci_unit, acb->firm_model, acb->firm_version);
+ acb->firm_request_len = CHIP_REG_READ32(HBE_MessageUnit, 0, msgcode_rwbuffer[1]); /*firm_request_len, 1, 04-07*/
+ acb->firm_numbers_queue = CHIP_REG_READ32(HBE_MessageUnit, 0, msgcode_rwbuffer[2]); /*firm_numbers_queue, 2, 08-11*/
+ acb->firm_sdram_size = CHIP_REG_READ32(HBE_MessageUnit, 0, msgcode_rwbuffer[3]); /*firm_sdram_size, 3, 12-15*/
+ acb->firm_ide_channels = CHIP_REG_READ32(HBE_MessageUnit, 0, msgcode_rwbuffer[4]); /*firm_ide_channels, 4, 16-19*/
+ acb->firm_cfg_version = CHIP_REG_READ32(HBE_MessageUnit, 0, msgcode_rwbuffer[ARCMSR_FW_CFGVER_OFFSET]); /*firm_cfg_version, 25, */
+ if(acb->firm_numbers_queue > ARCMSR_MAX_OUTSTANDING_CMD)
+ acb->maxOutstanding = ARCMSR_MAX_OUTSTANDING_CMD - 1;
+ else
+ acb->maxOutstanding = acb->firm_numbers_queue - 1;
+}
+/*
+**********************************************************************
+**********************************************************************
+*/
static void arcmsr_get_firmware_spec(struct AdapterControlBlock *acb)
{
switch (acb->adapter_type) {
@@ -3634,6 +4022,10 @@ static void arcmsr_get_firmware_spec(struct AdapterCon
arcmsr_get_hbd_config(acb);
}
break;
+ case ACB_ADAPTER_TYPE_E: {
+ arcmsr_get_hbe_config(acb);
+ }
+ break;
}
}
/*
@@ -3695,6 +4087,18 @@ static void arcmsr_wait_firmware_ready( struct Adapter
}
}
break;
+ case ACB_ADAPTER_TYPE_E: {
+ while ((CHIP_REG_READ32(HBE_MessageUnit, 0, outbound_msgaddr1) & ARCMSR_HBEMU_MESSAGE_FIRMWARE_OK) == 0)
+ {
+ if (timeout++ > 4000) /* (4000*15)/1000 = 60 sec */
+ {
+ printf( "arcmsr%d:timed out waiting for firmware ready\n", acb->pci_unit);
+ return;
+ }
+ UDELAY(15000); /* wait 15 milli-seconds */
+ }
+ }
+ break;
}
}
/*
@@ -3738,6 +4142,14 @@ static void arcmsr_clear_doorbell_queue_buffer( struct
}
break;
+ case ACB_ADAPTER_TYPE_E: {
+ /* empty doorbell Qbuffer if door bell ringed */
+ acb->in_doorbell = CHIP_REG_READ32(HBE_MessageUnit, 0, iobound_doorbell);
+ CHIP_REG_WRITE32(HBE_MessageUnit, 0, host_int_status, 0); /*clear doorbell interrupt */
+ acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_DATA_READ_OK;
+ CHIP_REG_WRITE32(HBE_MessageUnit, 0, iobound_doorbell, acb->out_doorbell);
+ }
+ break;
}
}
/*
@@ -3844,6 +4256,27 @@ static u_int32_t arcmsr_iop_confirm(struct AdapterCont
}
}
break;
+ case ACB_ADAPTER_TYPE_E: {
+ u_int32_t cdb_phyaddr_lo32;
+ cdb_phyaddr_lo32 = srb_phyaddr_lo32 + offsetof(struct CommandControlBlock, arcmsr_cdb);
+ CHIP_REG_WRITE32(HBE_MessageUnit, 0, msgcode_rwbuffer[0], ARCMSR_SIGNATURE_SET_CONFIG);
+ CHIP_REG_WRITE32(HBE_MessageUnit, 0, msgcode_rwbuffer[1], ARCMSR_SIGNATURE_1884);
+ CHIP_REG_WRITE32(HBE_MessageUnit, 0, msgcode_rwbuffer[2], cdb_phyaddr_lo32);
+ CHIP_REG_WRITE32(HBE_MessageUnit, 0, msgcode_rwbuffer[3], srb_phyaddr_hi32);
+ CHIP_REG_WRITE32(HBE_MessageUnit, 0, msgcode_rwbuffer[4], SRB_SIZE);
+ cdb_phyaddr_lo32 = srb_phyaddr_lo32 + ARCMSR_SRBS_POOL_SIZE;
+ CHIP_REG_WRITE32(HBE_MessageUnit, 0, msgcode_rwbuffer[5], cdb_phyaddr_lo32);
+ CHIP_REG_WRITE32(HBE_MessageUnit, 0, msgcode_rwbuffer[6], srb_phyaddr_hi32);
+ CHIP_REG_WRITE32(HBE_MessageUnit, 0, msgcode_rwbuffer[7], COMPLETION_Q_POOL_SIZE);
+ CHIP_REG_WRITE32(HBE_MessageUnit, 0, inbound_msgaddr0, ARCMSR_INBOUND_MESG0_SET_CONFIG);
+ acb->out_doorbell ^= ARCMSR_HBEMU_DRV2IOP_MESSAGE_CMD_DONE;
+ CHIP_REG_WRITE32(HBE_MessageUnit, 0, iobound_doorbell, acb->out_doorbell);
+ if(!arcmsr_hbe_wait_msgint_ready(acb)) {
+ printf( "arcmsr%d: 'set srb high part physical address' timeout \n", acb->pci_unit);
+ return FALSE;
+ }
+ }
+ break;
}
return (TRUE);
}
@@ -3853,21 +4286,14 @@ static u_int32_t arcmsr_iop_confirm(struct AdapterCont
*/
static void arcmsr_enable_eoi_mode(struct AdapterControlBlock *acb)
{
- switch (acb->adapter_type)
+ if (acb->adapter_type == ACB_ADAPTER_TYPE_B)
{
- case ACB_ADAPTER_TYPE_A:
- case ACB_ADAPTER_TYPE_C:
- case ACB_ADAPTER_TYPE_D:
- break;
- case ACB_ADAPTER_TYPE_B: {
- struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
- WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_MESSAGE_ACTIVE_EOI_MODE);
- if(!arcmsr_hbb_wait_msgint_ready(acb)) {
- printf( "arcmsr%d: 'iop enable eoi mode' timeout \n", acb->pci_unit);
- return;
- }
+ struct HBB_MessageUnit *phbbmu = (struct HBB_MessageUnit *)acb->pmu;
+ WRITE_CHIP_REG32(0, phbbmu->drv2iop_doorbell, ARCMSR_MESSAGE_ACTIVE_EOI_MODE);
+ if(!arcmsr_hbb_wait_msgint_ready(acb)) {
+ printf( "arcmsr%d: 'iop enable eoi mode' timeout \n", acb->pci_unit);
+ return;
}
- break;
}
}
/*
@@ -3913,7 +4339,8 @@ static void arcmsr_map_free_srb(void *arg, bus_dma_seg
" srb dmamap bus_dmamap_create error\n", acb->pci_unit);
return;
}
- if((acb->adapter_type == ACB_ADAPTER_TYPE_C) || (acb->adapter_type == ACB_ADAPTER_TYPE_D))
+ if((acb->adapter_type == ACB_ADAPTER_TYPE_C) || (acb->adapter_type == ACB_ADAPTER_TYPE_D)
+ || (acb->adapter_type == ACB_ADAPTER_TYPE_E))
{
srb_tmp->cdb_phyaddr_low = srb_phyaddr;
srb_tmp->cdb_phyaddr_high = (u_int32_t)((srb_phyaddr >> 16) >> 16);
@@ -3921,10 +4348,12 @@ static void arcmsr_map_free_srb(void *arg, bus_dma_seg
else
srb_tmp->cdb_phyaddr_low = 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);
}
+ acb->pCompletionQ = (pCompletion_Q)srb_tmp;
acb->vir2phy_offset = (unsigned long)srb_tmp - (unsigned long)srb_phyaddr;
}
/*
@@ -3992,6 +4421,12 @@ static u_int32_t arcmsr_initialize(device_t dev)
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 PCIDevVenIDARC1214: {
acb->adapter_type = ACB_ADAPTER_TYPE_D;
acb->adapter_bus_speed = ACB_BUS_SPEED_6G;
@@ -4140,141 +4575,177 @@ static u_int32_t arcmsr_initialize(device_t dev)
pci_write_config(dev, PCIR_COMMAND, pci_command, 2);
switch(acb->adapter_type) {
case ACB_ADAPTER_TYPE_A: {
- u_int32_t rid0 = PCIR_BAR(0);
- vm_offset_t mem_base0;
+ 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));
- 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));
- 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));
- 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 *)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));
+ 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));
+ 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));
+ 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 *)mem_base0;
+ acb->rid = 0;
+ }
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_long size;
- if (vendor_dev_id == PCIDevVenIDARC1203)
- size = sizeof(struct HBB_DOORBELL_1203);
- else
- size = sizeof(struct HBB_DOORBELL);
- for(i=0; i < 2; i++) {
- if(i == 0) {
- acb->sys_res_arcmsr[i] = bus_alloc_resource_any(dev,SYS_RES_MEMORY, &rid[i],
- RF_ACTIVE);
- } else {
- 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);
- 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);
- 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);
- 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);
+ 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_long size;
+ if (vendor_dev_id == PCIDevVenIDARC1203)
+ size = sizeof(struct HBB_DOORBELL_1203);
+ else
+ size = sizeof(struct HBB_DOORBELL);
+ for(i=0; i < 2; i++) {
+ if(i == 0) {
+ acb->sys_res_arcmsr[i] = bus_alloc_resource_any(dev,SYS_RES_MEMORY, &rid[i],
+ RF_ACTIVE);
} 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->sys_res_arcmsr[i] = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid[i],
+ RF_ACTIVE);
}
- }
- break;
- case ACB_ADAPTER_TYPE_C: {
- u_int32_t rid0 = PCIR_BAR(1);
- 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) {
+ if(acb->sys_res_arcmsr[i] == NULL) {
arcmsr_free_resource(acb);
- printf("arcmsr%d: bus_alloc_resource failure!\n", device_get_unit(dev));
+ printf("arcmsr%d: bus_alloc_resource %d failure!\n", device_get_unit(dev), i);
return ENOMEM;
}
- if(rman_get_start(acb->sys_res_arcmsr[0]) <= 0) {
+ if(rman_get_start(acb->sys_res_arcmsr[i]) <= 0) {
arcmsr_free_resource(acb);
- printf("arcmsr%d: rman_get_start failure!\n", device_get_unit(dev));
+ printf("arcmsr%d: rman_get_start %d failure!\n", device_get_unit(dev), i);
return ENXIO;
}
- mem_base0 = (vm_offset_t) rman_get_virtual(acb->sys_res_arcmsr[0]);
- if(mem_base0 == 0) {
+ 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 failure!\n", device_get_unit(dev));
+ printf("arcmsr%d: rman_get_virtual %d failure!\n", device_get_unit(dev), i);
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 *)mem_base0;
+ 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->rid = 0;
+ }
break;
+ case ACB_ADAPTER_TYPE_C: {
+ u_int32_t rid0 = PCIR_BAR(1);
+ 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));
+ 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));
+ 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));
+ 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 *)mem_base0;
+ acb->rid = 1;
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-all
mailing list