A chunk of cleanup, both stylistic and substantive.
We now also read configuration information for the SCSI cards- this allows us to try and say what the speed settings now are. Start, but not yet complete, the process of reorgs && #defines so that we can backport to RELENG_4 pretty soon.
This commit is contained in:
parent
a79225f8d0
commit
725cb72df3
@ -31,7 +31,7 @@
|
||||
*/
|
||||
|
||||
#include <dev/mpt/mpt_freebsd.h>
|
||||
#include <dev/mpt/mpt.h>
|
||||
|
||||
#define MPT_MAX_TRYS 3
|
||||
#define MPT_MAX_WAIT 300000
|
||||
|
||||
@ -39,24 +39,24 @@ static int maxwait_ack = 0;
|
||||
static int maxwait_int = 0;
|
||||
static int maxwait_state = 0;
|
||||
|
||||
static __inline u_int32_t mpt_rd_db(struct mpt_softc *mpt);
|
||||
static __inline u_int32_t mpt_rd_intr(struct mpt_softc *mpt);
|
||||
static __inline u_int32_t mpt_rd_db(mpt_softc_t *mpt);
|
||||
static __inline u_int32_t mpt_rd_intr(mpt_softc_t *mpt);
|
||||
|
||||
static __inline u_int32_t
|
||||
mpt_rd_db(struct mpt_softc *mpt)
|
||||
mpt_rd_db(mpt_softc_t *mpt)
|
||||
{
|
||||
return mpt_read(mpt, MPT_OFFSET_DOORBELL);
|
||||
}
|
||||
|
||||
static __inline u_int32_t
|
||||
mpt_rd_intr(struct mpt_softc *mpt)
|
||||
mpt_rd_intr(mpt_softc_t *mpt)
|
||||
{
|
||||
return mpt_read(mpt, MPT_OFFSET_INTR_STATUS);
|
||||
}
|
||||
|
||||
/* Busy wait for a door bell to be read by IOC */
|
||||
static int
|
||||
mpt_wait_db_ack(struct mpt_softc *mpt)
|
||||
mpt_wait_db_ack(mpt_softc_t *mpt)
|
||||
{
|
||||
int i;
|
||||
for (i=0; i < MPT_MAX_WAIT; i++) {
|
||||
@ -72,7 +72,7 @@ mpt_wait_db_ack(struct mpt_softc *mpt)
|
||||
|
||||
/* Busy wait for a door bell interrupt */
|
||||
static int
|
||||
mpt_wait_db_int(struct mpt_softc *mpt)
|
||||
mpt_wait_db_int(mpt_softc_t *mpt)
|
||||
{
|
||||
int i;
|
||||
for (i=0; i < MPT_MAX_WAIT; i++) {
|
||||
@ -87,7 +87,7 @@ mpt_wait_db_int(struct mpt_softc *mpt)
|
||||
|
||||
/* Wait for IOC to transition to a give state */
|
||||
void
|
||||
mpt_check_doorbell(struct mpt_softc *mpt)
|
||||
mpt_check_doorbell(mpt_softc_t *mpt)
|
||||
{
|
||||
u_int32_t db = mpt_rd_db(mpt);
|
||||
if (MPT_STATE(db) != MPT_DB_STATE_RUNNING) {
|
||||
@ -98,7 +98,7 @@ mpt_check_doorbell(struct mpt_softc *mpt)
|
||||
|
||||
/* Wait for IOC to transition to a give state */
|
||||
static int
|
||||
mpt_wait_state(struct mpt_softc *mpt, enum DB_STATE_BITS state)
|
||||
mpt_wait_state(mpt_softc_t *mpt, enum DB_STATE_BITS state)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -116,7 +116,7 @@ mpt_wait_state(struct mpt_softc *mpt, enum DB_STATE_BITS state)
|
||||
|
||||
/* Issue the reset COMMAND to the IOC */
|
||||
int
|
||||
mpt_soft_reset(struct mpt_softc *mpt)
|
||||
mpt_soft_reset(mpt_softc_t *mpt)
|
||||
{
|
||||
if (mpt->verbose) {
|
||||
device_printf(mpt->dev,"soft reset\n");
|
||||
@ -160,7 +160,7 @@ mpt_soft_reset(struct mpt_softc *mpt)
|
||||
* processors in the chip.
|
||||
*/
|
||||
void
|
||||
mpt_hard_reset(struct mpt_softc *mpt)
|
||||
mpt_hard_reset(mpt_softc_t *mpt)
|
||||
{
|
||||
/* This extra read comes for the Linux source
|
||||
* released by LSI. It's function is undocumented!
|
||||
@ -204,7 +204,7 @@ mpt_hard_reset(struct mpt_softc *mpt)
|
||||
* fouls up the PCI configuration registers.
|
||||
*/
|
||||
int
|
||||
mpt_reset(struct mpt_softc *mpt)
|
||||
mpt_reset(mpt_softc_t *mpt)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@ -225,7 +225,7 @@ mpt_reset(struct mpt_softc *mpt)
|
||||
|
||||
/* Return a command buffer to the free queue */
|
||||
void
|
||||
mpt_free_request(struct mpt_softc *mpt, request_t *req)
|
||||
mpt_free_request(mpt_softc_t *mpt, request_t *req)
|
||||
{
|
||||
if (req == NULL || req != &mpt->requests[req->index]) {
|
||||
panic("mpt_free_request bad req ptr\n");
|
||||
@ -238,7 +238,7 @@ mpt_free_request(struct mpt_softc *mpt, request_t *req)
|
||||
|
||||
/* Get a command buffer from the free queue */
|
||||
request_t *
|
||||
mpt_get_request(struct mpt_softc *mpt)
|
||||
mpt_get_request(mpt_softc_t *mpt)
|
||||
{
|
||||
request_t *req;
|
||||
req = SLIST_FIRST(&mpt->request_free_list);
|
||||
@ -257,7 +257,7 @@ mpt_get_request(struct mpt_softc *mpt)
|
||||
|
||||
/* Pass the command to the IOC */
|
||||
void
|
||||
mpt_send_cmd(struct mpt_softc *mpt, request_t *req)
|
||||
mpt_send_cmd(mpt_softc_t *mpt, request_t *req)
|
||||
{
|
||||
req->sequence = mpt->sequence++;
|
||||
if (mpt->verbose > 1) {
|
||||
@ -285,14 +285,14 @@ mpt_send_cmd(struct mpt_softc *mpt, request_t *req)
|
||||
* finished processing it.
|
||||
*/
|
||||
void
|
||||
mpt_free_reply(struct mpt_softc *mpt, u_int32_t ptr)
|
||||
mpt_free_reply(mpt_softc_t *mpt, u_int32_t ptr)
|
||||
{
|
||||
mpt_write(mpt, MPT_OFFSET_REPLY_Q, ptr);
|
||||
}
|
||||
|
||||
/* Get a reply from the IOC */
|
||||
u_int32_t
|
||||
mpt_pop_reply_queue(struct mpt_softc *mpt)
|
||||
mpt_pop_reply_queue(mpt_softc_t *mpt)
|
||||
{
|
||||
return mpt_read(mpt, MPT_OFFSET_REPLY_Q);
|
||||
}
|
||||
@ -304,7 +304,7 @@ mpt_pop_reply_queue(struct mpt_softc *mpt)
|
||||
* commands such as device/bus reset as specified by LSI.
|
||||
*/
|
||||
int
|
||||
mpt_send_handshake_cmd(struct mpt_softc *mpt, size_t len, void *cmd)
|
||||
mpt_send_handshake_cmd(mpt_softc_t *mpt, size_t len, void *cmd)
|
||||
{
|
||||
int i;
|
||||
u_int32_t data, *data32;
|
||||
@ -365,7 +365,7 @@ mpt_send_handshake_cmd(struct mpt_softc *mpt, size_t len, void *cmd)
|
||||
|
||||
/* Get the response from the handshake register */
|
||||
int
|
||||
mpt_recv_handshake_reply(struct mpt_softc *mpt, size_t reply_len, void *reply)
|
||||
mpt_recv_handshake_reply(mpt_softc_t *mpt, size_t reply_len, void *reply)
|
||||
{
|
||||
int left, reply_left;
|
||||
u_int16_t *data16;
|
||||
@ -436,9 +436,8 @@ mpt_recv_handshake_reply(struct mpt_softc *mpt, size_t reply_len, void *reply)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Get API statistics from the chip */
|
||||
static int
|
||||
mpt_get_iocfacts(struct mpt_softc *mpt, MSG_IOC_FACTS_REPLY *freplp)
|
||||
mpt_get_iocfacts(mpt_softc_t *mpt, MSG_IOC_FACTS_REPLY *freplp)
|
||||
{
|
||||
MSG_IOC_FACTS f_req;
|
||||
int error;
|
||||
@ -453,6 +452,23 @@ mpt_get_iocfacts(struct mpt_softc *mpt, MSG_IOC_FACTS_REPLY *freplp)
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
mpt_get_portfacts(mpt_softc_t *mpt, MSG_PORT_FACTS_REPLY *freplp)
|
||||
{
|
||||
MSG_PORT_FACTS f_req;
|
||||
int error;
|
||||
|
||||
/* XXX: Only getting PORT FACTS for Port 0 */
|
||||
bzero(&f_req, sizeof f_req);
|
||||
f_req.Function = MPI_FUNCTION_PORT_FACTS;
|
||||
f_req.MsgContext = 0x12071943;
|
||||
error = mpt_send_handshake_cmd(mpt, sizeof f_req, &f_req);
|
||||
if (error)
|
||||
return(error);
|
||||
error = mpt_recv_handshake_reply(mpt, sizeof (*freplp), freplp);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Send the initialization request. This is where we specify how many
|
||||
* SCSI busses and how many devices per bus we wish to emulate.
|
||||
@ -460,7 +476,7 @@ mpt_get_iocfacts(struct mpt_softc *mpt, MSG_IOC_FACTS_REPLY *freplp)
|
||||
* frames from the IOC that we will be allocating.
|
||||
*/
|
||||
static int
|
||||
mpt_send_ioc_init(struct mpt_softc *mpt, u_int32_t who)
|
||||
mpt_send_ioc_init(mpt_softc_t *mpt, u_int32_t who)
|
||||
{
|
||||
int error = 0;
|
||||
MSG_IOC_INIT init;
|
||||
@ -486,9 +502,446 @@ mpt_send_ioc_init(struct mpt_softc *mpt, u_int32_t who)
|
||||
return (error);
|
||||
}
|
||||
|
||||
/* Send the port enable to allow the IOC to join the FC loop */
|
||||
|
||||
/*
|
||||
* Utiltity routine to read configuration headers and pages
|
||||
*/
|
||||
|
||||
static int
|
||||
mpt_send_port_enable(struct mpt_softc *mpt, int port)
|
||||
mpt_read_cfg_header(mpt_softc_t *, int, int, int, fCONFIG_PAGE_HEADER *);
|
||||
static int
|
||||
mpt_read_cfg_page(mpt_softc_t *, int, fCONFIG_PAGE_HEADER *);
|
||||
static int
|
||||
mpt_write_cfg_page(mpt_softc_t *, int, fCONFIG_PAGE_HEADER *);
|
||||
|
||||
static int
|
||||
mpt_read_cfg_header(mpt_softc_t *mpt, int PageType, int PageNumber,
|
||||
int PageAddress, fCONFIG_PAGE_HEADER *rslt)
|
||||
{
|
||||
int count;
|
||||
request_t *req;
|
||||
MSG_CONFIG *cfgp;
|
||||
MSG_CONFIG_REPLY *reply;
|
||||
|
||||
req = mpt_get_request(mpt);
|
||||
|
||||
cfgp = req->req_vbuf;
|
||||
bzero(cfgp, sizeof *cfgp);
|
||||
|
||||
cfgp->Action = MPI_CONFIG_ACTION_PAGE_HEADER;
|
||||
cfgp->Function = MPI_FUNCTION_CONFIG;
|
||||
cfgp->Header.PageNumber = (U8) PageNumber;
|
||||
cfgp->Header.PageType = (U8) PageType;
|
||||
cfgp->PageAddress = PageAddress;
|
||||
MPI_pSGE_SET_FLAGS(((SGE_SIMPLE32 *) &cfgp->PageBufferSGE),
|
||||
(MPI_SGE_FLAGS_LAST_ELEMENT | MPI_SGE_FLAGS_END_OF_BUFFER |
|
||||
MPI_SGE_FLAGS_SIMPLE_ELEMENT | MPI_SGE_FLAGS_END_OF_LIST));
|
||||
cfgp->MsgContext = req->index | 0x80000000;
|
||||
|
||||
mpt_check_doorbell(mpt);
|
||||
mpt_send_cmd(mpt, req);
|
||||
count = 0;
|
||||
do {
|
||||
DELAY(500);
|
||||
mpt_intr(mpt);
|
||||
if (++count == 1000) {
|
||||
device_printf(mpt->dev, "read_cfg_header timed out\n");
|
||||
return (-1);
|
||||
}
|
||||
} while (req->debug == REQ_ON_CHIP);
|
||||
|
||||
reply = (MSG_CONFIG_REPLY *) MPT_REPLY_PTOV(mpt, req->sequence);
|
||||
if ((reply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
|
||||
device_printf(mpt->dev,
|
||||
"mpt_read_cfg_header: Config Info Status %x\n",
|
||||
reply->IOCStatus);
|
||||
return (-1);
|
||||
}
|
||||
bcopy(&reply->Header, rslt, sizeof (fCONFIG_PAGE_HEADER));
|
||||
mpt_free_reply(mpt, (req->sequence << 1));
|
||||
mpt_free_request(mpt, req);
|
||||
return (0);
|
||||
}
|
||||
|
||||
#define CFG_DATA_OFF 40
|
||||
|
||||
static int
|
||||
mpt_read_cfg_page(mpt_softc_t *mpt, int PageAddress, fCONFIG_PAGE_HEADER *hdr)
|
||||
{
|
||||
int count;
|
||||
request_t *req;
|
||||
SGE_SIMPLE32 *se;
|
||||
MSG_CONFIG *cfgp;
|
||||
size_t amt;
|
||||
MSG_CONFIG_REPLY *reply;
|
||||
|
||||
req = mpt_get_request(mpt);
|
||||
|
||||
cfgp = req->req_vbuf;
|
||||
amt = (cfgp->Header.PageLength * sizeof (uint32_t));
|
||||
bzero(cfgp, sizeof *cfgp);
|
||||
cfgp->Action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
|
||||
cfgp->Function = MPI_FUNCTION_CONFIG;
|
||||
cfgp->Header = *hdr;
|
||||
cfgp->Header.PageType &= MPI_CONFIG_PAGETYPE_MASK;
|
||||
cfgp->PageAddress = PageAddress;
|
||||
se = (SGE_SIMPLE32 *) &cfgp->PageBufferSGE;
|
||||
se->Address = req->req_pbuf + CFG_DATA_OFF;
|
||||
MPI_pSGE_SET_LENGTH(se, amt);
|
||||
MPI_pSGE_SET_FLAGS(se, (MPI_SGE_FLAGS_SIMPLE_ELEMENT |
|
||||
MPI_SGE_FLAGS_LAST_ELEMENT | MPI_SGE_FLAGS_END_OF_BUFFER |
|
||||
MPI_SGE_FLAGS_END_OF_LIST));
|
||||
|
||||
cfgp->MsgContext = req->index | 0x80000000;
|
||||
|
||||
mpt_check_doorbell(mpt);
|
||||
mpt_send_cmd(mpt, req);
|
||||
count = 0;
|
||||
do {
|
||||
DELAY(500);
|
||||
mpt_intr(mpt);
|
||||
if (++count == 1000) {
|
||||
device_printf(mpt->dev, "read_cfg_page timed out\n");
|
||||
return (-1);
|
||||
}
|
||||
} while (req->debug == REQ_ON_CHIP);
|
||||
|
||||
reply = (MSG_CONFIG_REPLY *) MPT_REPLY_PTOV(mpt, req->sequence);
|
||||
if ((reply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
|
||||
device_printf(mpt->dev,
|
||||
"mpt_read_cfg_page: Config Info Status %x\n",
|
||||
reply->IOCStatus);
|
||||
return (-1);
|
||||
}
|
||||
mpt_free_reply(mpt, (req->sequence << 1));
|
||||
bus_dmamap_sync(mpt->request_dmat, mpt->request_dmap,
|
||||
BUS_DMASYNC_POSTREAD);
|
||||
if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT &&
|
||||
cfgp->Header.PageNumber == 0) {
|
||||
amt = sizeof (fCONFIG_PAGE_SCSI_PORT_0);
|
||||
} else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT &&
|
||||
cfgp->Header.PageNumber == 1) {
|
||||
amt = sizeof (fCONFIG_PAGE_SCSI_PORT_1);
|
||||
} else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT &&
|
||||
cfgp->Header.PageNumber == 2) {
|
||||
amt = sizeof (fCONFIG_PAGE_SCSI_PORT_2);
|
||||
} else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_DEVICE &&
|
||||
cfgp->Header.PageNumber == 0) {
|
||||
amt = sizeof (fCONFIG_PAGE_SCSI_DEVICE_0);
|
||||
} else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_DEVICE &&
|
||||
cfgp->Header.PageNumber == 1) {
|
||||
amt = sizeof (fCONFIG_PAGE_SCSI_DEVICE_1);
|
||||
}
|
||||
bcopy(((caddr_t)req->req_vbuf)+CFG_DATA_OFF, hdr, amt);
|
||||
mpt_free_request(mpt, req);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
mpt_write_cfg_page(mpt_softc_t *mpt, int PageAddress, fCONFIG_PAGE_HEADER *hdr)
|
||||
{
|
||||
int count, hdr_attr;
|
||||
request_t *req;
|
||||
SGE_SIMPLE32 *se;
|
||||
MSG_CONFIG *cfgp;
|
||||
size_t amt;
|
||||
MSG_CONFIG_REPLY *reply;
|
||||
|
||||
req = mpt_get_request(mpt);
|
||||
|
||||
cfgp = req->req_vbuf;
|
||||
bzero(cfgp, sizeof *cfgp);
|
||||
|
||||
hdr_attr = hdr->PageType & MPI_CONFIG_PAGEATTR_MASK;
|
||||
if (hdr_attr != MPI_CONFIG_PAGEATTR_CHANGEABLE &&
|
||||
hdr_attr != MPI_CONFIG_PAGEATTR_PERSISTENT) {
|
||||
device_printf(mpt->dev, "page type 0x%x not changeable\n",
|
||||
hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
|
||||
return (-1);
|
||||
}
|
||||
hdr->PageType &= MPI_CONFIG_PAGETYPE_MASK;
|
||||
|
||||
amt = (cfgp->Header.PageLength * sizeof (uint32_t));
|
||||
cfgp->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
|
||||
cfgp->Function = MPI_FUNCTION_CONFIG;
|
||||
cfgp->Header = *hdr;
|
||||
cfgp->PageAddress = PageAddress;
|
||||
|
||||
se = (SGE_SIMPLE32 *) &cfgp->PageBufferSGE;
|
||||
se->Address = req->req_pbuf + CFG_DATA_OFF;
|
||||
MPI_pSGE_SET_LENGTH(se, amt);
|
||||
MPI_pSGE_SET_FLAGS(se, (MPI_SGE_FLAGS_SIMPLE_ELEMENT |
|
||||
MPI_SGE_FLAGS_LAST_ELEMENT | MPI_SGE_FLAGS_END_OF_BUFFER |
|
||||
MPI_SGE_FLAGS_END_OF_LIST | MPI_SGE_FLAGS_HOST_TO_IOC));
|
||||
|
||||
cfgp->MsgContext = req->index | 0x80000000;
|
||||
|
||||
if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT &&
|
||||
cfgp->Header.PageNumber == 0) {
|
||||
amt = sizeof (fCONFIG_PAGE_SCSI_PORT_0);
|
||||
} else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT &&
|
||||
cfgp->Header.PageNumber == 1) {
|
||||
amt = sizeof (fCONFIG_PAGE_SCSI_PORT_1);
|
||||
} else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT &&
|
||||
cfgp->Header.PageNumber == 2) {
|
||||
amt = sizeof (fCONFIG_PAGE_SCSI_PORT_2);
|
||||
} else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_DEVICE &&
|
||||
cfgp->Header.PageNumber == 0) {
|
||||
amt = sizeof (fCONFIG_PAGE_SCSI_DEVICE_0);
|
||||
} else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_DEVICE &&
|
||||
cfgp->Header.PageNumber == 1) {
|
||||
amt = sizeof (fCONFIG_PAGE_SCSI_DEVICE_1);
|
||||
}
|
||||
bcopy(hdr, ((caddr_t)req->req_vbuf)+CFG_DATA_OFF, amt);
|
||||
|
||||
mpt_check_doorbell(mpt);
|
||||
mpt_send_cmd(mpt, req);
|
||||
count = 0;
|
||||
do {
|
||||
DELAY(500);
|
||||
mpt_intr(mpt);
|
||||
if (++count == 1000) {
|
||||
hdr->PageType |= hdr_attr;
|
||||
device_printf(mpt->dev,
|
||||
"mpt_write_cfg_page timed out\n");
|
||||
return (-1);
|
||||
}
|
||||
} while (req->debug == REQ_ON_CHIP);
|
||||
|
||||
reply = (MSG_CONFIG_REPLY *) MPT_REPLY_PTOV(mpt, req->sequence);
|
||||
if ((reply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
|
||||
device_printf(mpt->dev,
|
||||
"mpt_write_cfg_page: Config Info Status %x\n",
|
||||
reply->IOCStatus);
|
||||
return (-1);
|
||||
}
|
||||
mpt_free_reply(mpt, (req->sequence << 1));
|
||||
|
||||
/*
|
||||
* Restore stripped out attributes
|
||||
*/
|
||||
hdr->PageType |= hdr_attr;
|
||||
mpt_free_request(mpt, req);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read SCSI configuration information
|
||||
*/
|
||||
static int
|
||||
mpt_read_config_info_spi(mpt_softc_t *mpt)
|
||||
{
|
||||
int rv, i;
|
||||
|
||||
rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_PORT, 0,
|
||||
0, &mpt->mpt_port_page0.Header);
|
||||
if (rv) {
|
||||
return (-1);
|
||||
}
|
||||
if (mpt->verbose > 1) {
|
||||
device_printf(mpt->dev, "SPI Port Page 0 Header: %x %x %x %x\n",
|
||||
mpt->mpt_port_page0.Header.PageVersion,
|
||||
mpt->mpt_port_page0.Header.PageLength,
|
||||
mpt->mpt_port_page0.Header.PageNumber,
|
||||
mpt->mpt_port_page0.Header.PageType);
|
||||
}
|
||||
|
||||
rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_PORT, 1,
|
||||
0, &mpt->mpt_port_page1.Header);
|
||||
if (rv) {
|
||||
return (-1);
|
||||
}
|
||||
if (mpt->verbose > 1) {
|
||||
device_printf(mpt->dev, "SPI Port Page 1 Header: %x %x %x %x\n",
|
||||
mpt->mpt_port_page1.Header.PageVersion,
|
||||
mpt->mpt_port_page1.Header.PageLength,
|
||||
mpt->mpt_port_page1.Header.PageNumber,
|
||||
mpt->mpt_port_page1.Header.PageType);
|
||||
}
|
||||
|
||||
rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_PORT, 2,
|
||||
0, &mpt->mpt_port_page2.Header);
|
||||
if (rv) {
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (mpt->verbose > 1) {
|
||||
device_printf(mpt->dev, "SPI Port Page 2 Header: %x %x %x %x\n",
|
||||
mpt->mpt_port_page1.Header.PageVersion,
|
||||
mpt->mpt_port_page1.Header.PageLength,
|
||||
mpt->mpt_port_page1.Header.PageNumber,
|
||||
mpt->mpt_port_page1.Header.PageType);
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_DEVICE,
|
||||
0, i, &mpt->mpt_dev_page0[i].Header);
|
||||
if (rv) {
|
||||
return (-1);
|
||||
}
|
||||
if (mpt->verbose > 1) {
|
||||
device_printf(mpt->dev,
|
||||
"SPI Target %d Device Page 0 Header: %x %x %x %x\n",
|
||||
i, mpt->mpt_dev_page0[i].Header.PageVersion,
|
||||
mpt->mpt_dev_page0[i].Header.PageLength,
|
||||
mpt->mpt_dev_page0[i].Header.PageNumber,
|
||||
mpt->mpt_dev_page0[i].Header.PageType);
|
||||
}
|
||||
|
||||
rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_DEVICE,
|
||||
1, i, &mpt->mpt_dev_page1[i].Header);
|
||||
if (rv) {
|
||||
return (-1);
|
||||
}
|
||||
if (mpt->verbose > 1) {
|
||||
device_printf(mpt->dev,
|
||||
"SPI Target %d Device Page 1 Header: %x %x %x %x\n",
|
||||
i, mpt->mpt_dev_page1[i].Header.PageVersion,
|
||||
mpt->mpt_dev_page1[i].Header.PageLength,
|
||||
mpt->mpt_dev_page1[i].Header.PageNumber,
|
||||
mpt->mpt_dev_page1[i].Header.PageType);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* At this point, we don't *have* to fail. As long as we have
|
||||
* valid config header information, we can (barely) lurch
|
||||
* along.
|
||||
*/
|
||||
|
||||
rv = mpt_read_cfg_page(mpt, 0, &mpt->mpt_port_page0.Header);
|
||||
if (rv) {
|
||||
device_printf(mpt->dev, "failed to read SPI Port Page 0\n");
|
||||
} else if (mpt->verbose > 1) {
|
||||
device_printf(mpt->dev,
|
||||
"SPI Port Page 0: Capabilities %x PhysicalInterface %x\n",
|
||||
mpt->mpt_port_page0.Capabilities,
|
||||
mpt->mpt_port_page0.PhysicalInterface);
|
||||
}
|
||||
|
||||
rv = mpt_read_cfg_page(mpt, 0, &mpt->mpt_port_page1.Header);
|
||||
if (rv) {
|
||||
device_printf(mpt->dev, "failed to read SPI Port Page 1\n");
|
||||
} else if (mpt->verbose > 1) {
|
||||
device_printf(mpt->dev,
|
||||
"SPI Port Page 1: Configuration %x OnBusTimerValue %x\n",
|
||||
mpt->mpt_port_page1.Configuration,
|
||||
mpt->mpt_port_page1.OnBusTimerValue);
|
||||
}
|
||||
|
||||
rv = mpt_read_cfg_page(mpt, 0, &mpt->mpt_port_page2.Header);
|
||||
if (rv) {
|
||||
device_printf(mpt->dev, "failed to read SPI Port Page 2\n");
|
||||
} else if (mpt->verbose > 1) {
|
||||
device_printf(mpt->dev,
|
||||
"SPI Port Page 2: Flags %x Settings %x\n",
|
||||
mpt->mpt_port_page2.PortFlags,
|
||||
mpt->mpt_port_page2.PortSettings);
|
||||
for (i = 0; i < 16; i++) {
|
||||
device_printf(mpt->dev,
|
||||
"SPI Port Page 2 Tgt %d: timo %x SF %x Flags %x\n",
|
||||
i, mpt->mpt_port_page2.DeviceSettings[i].Timeout,
|
||||
mpt->mpt_port_page2.DeviceSettings[i].SyncFactor,
|
||||
mpt->mpt_port_page2.DeviceSettings[i].DeviceFlags);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
rv = mpt_read_cfg_page(mpt, i, &mpt->mpt_dev_page0[i].Header);
|
||||
if (rv) {
|
||||
device_printf(mpt->dev,
|
||||
"cannot read SPI Tgt %d Device Page 0\n", i);
|
||||
continue;
|
||||
}
|
||||
if (mpt->verbose > 1) {
|
||||
device_printf(mpt->dev,
|
||||
"SPI Tgt %d Page 0: NParms %x Information %x\n",
|
||||
i, mpt->mpt_dev_page0[i].NegotiatedParameters,
|
||||
mpt->mpt_dev_page0[i].Information);
|
||||
}
|
||||
rv = mpt_read_cfg_page(mpt, i, &mpt->mpt_dev_page1[i].Header);
|
||||
if (rv) {
|
||||
device_printf(mpt->dev,
|
||||
"cannot read SPI Tgt %d Device Page 1\n", i);
|
||||
continue;
|
||||
}
|
||||
if (mpt->verbose > 1) {
|
||||
device_printf(mpt->dev,
|
||||
"SPI Tgt %d Page 1: RParms %x Configuration %x\n",
|
||||
i, mpt->mpt_dev_page1[i].RequestedParameters,
|
||||
mpt->mpt_dev_page1[i].Configuration);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Validate SPI configuration information.
|
||||
*
|
||||
* In particular, validate SPI Port Page 1.
|
||||
*/
|
||||
static int
|
||||
mpt_set_initial_config_spi(mpt_softc_t *mpt)
|
||||
{
|
||||
int i, pp1val = ((1 << mpt->mpt_ini_id) << 16) | mpt->mpt_ini_id;
|
||||
|
||||
if (mpt->mpt_port_page1.Configuration != pp1val) {
|
||||
fCONFIG_PAGE_SCSI_PORT_1 tmp;
|
||||
device_printf(mpt->dev,
|
||||
"SPI Port Page 1 Config value bad (%x)- should be %x\n",
|
||||
mpt->mpt_port_page1.Configuration, pp1val);
|
||||
tmp = mpt->mpt_port_page1;
|
||||
tmp.Configuration = pp1val;
|
||||
if (mpt_write_cfg_page(mpt, 0, &tmp.Header)) {
|
||||
return (-1);
|
||||
}
|
||||
if (mpt_read_cfg_page(mpt, 0, &tmp.Header)) {
|
||||
return (-1);
|
||||
}
|
||||
if (tmp.Configuration != pp1val) {
|
||||
device_printf(mpt->dev,
|
||||
"failed to reset SPI Port Page 1 Config value\n");
|
||||
return (-1);
|
||||
}
|
||||
mpt->mpt_port_page1 = tmp;
|
||||
}
|
||||
|
||||
#if 1
|
||||
i = i;
|
||||
#else
|
||||
for (i = 0; i < 16; i++) {
|
||||
fCONFIG_PAGE_SCSI_DEVICE_1 tmp;
|
||||
tmp = mpt->mpt_dev_page1[i];
|
||||
tmp.RequestedParameters = 0;
|
||||
tmp.Configuration = 0;
|
||||
if (mpt->verbose > 1) {
|
||||
device_printf(mpt->dev,
|
||||
"Set Tgt %d SPI DevicePage 1 values to %x 0 %x\n",
|
||||
i, tmp.RequestedParameters, tmp.Configuration);
|
||||
}
|
||||
if (mpt_write_cfg_page(mpt, i, &tmp.Header)) {
|
||||
return (-1);
|
||||
}
|
||||
if (mpt_read_cfg_page(mpt, i, &tmp.Header)) {
|
||||
return (-1);
|
||||
}
|
||||
mpt->mpt_dev_page1[i] = tmp;
|
||||
if (mpt->verbose > 1) {
|
||||
device_printf(mpt->dev,
|
||||
"SPI Tgt %d Page 1: RParm %x Configuration %x\n", i,
|
||||
mpt->mpt_dev_page1[i].RequestedParameters,
|
||||
mpt->mpt_dev_page1[i].Configuration);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable IOC port
|
||||
*/
|
||||
static int
|
||||
mpt_send_port_enable(mpt_softc_t *mpt, int port)
|
||||
{
|
||||
int count;
|
||||
request_t *req;
|
||||
@ -529,7 +982,7 @@ mpt_send_port_enable(struct mpt_softc *mpt, int port)
|
||||
* instead of the handshake register.
|
||||
*/
|
||||
static int
|
||||
mpt_send_event_request(struct mpt_softc *mpt, int onoff)
|
||||
mpt_send_event_request(mpt_softc_t *mpt, int onoff)
|
||||
{
|
||||
request_t *req;
|
||||
MSG_EVENT_NOTIFY *enable_req;
|
||||
@ -557,7 +1010,7 @@ mpt_send_event_request(struct mpt_softc *mpt, int onoff)
|
||||
* Un-mask the interupts on the chip.
|
||||
*/
|
||||
void
|
||||
mpt_enable_ints(struct mpt_softc *mpt)
|
||||
mpt_enable_ints(mpt_softc_t *mpt)
|
||||
{
|
||||
/* Unmask every thing except door bell int */
|
||||
mpt_write(mpt, MPT_OFFSET_INTR_MASK, MPT_INTR_DB_MASK);
|
||||
@ -567,7 +1020,7 @@ mpt_enable_ints(struct mpt_softc *mpt)
|
||||
* Mask the interupts on the chip.
|
||||
*/
|
||||
void
|
||||
mpt_disable_ints(struct mpt_softc *mpt)
|
||||
mpt_disable_ints(mpt_softc_t *mpt)
|
||||
{
|
||||
/* Mask all interrupts */
|
||||
mpt_write(mpt, MPT_OFFSET_INTR_MASK,
|
||||
@ -576,10 +1029,11 @@ mpt_disable_ints(struct mpt_softc *mpt)
|
||||
|
||||
/* (Re)Initialize the chip for use */
|
||||
int
|
||||
mpt_init(struct mpt_softc *mpt, u_int32_t who)
|
||||
mpt_init(mpt_softc_t *mpt, u_int32_t who)
|
||||
{
|
||||
int try;
|
||||
MSG_IOC_FACTS_REPLY facts;
|
||||
MSG_PORT_FACTS_REPLY pfp;
|
||||
u_int32_t pptr;
|
||||
int val;
|
||||
|
||||
@ -629,20 +1083,51 @@ mpt_init(struct mpt_softc *mpt, u_int32_t who)
|
||||
if (mpt_get_iocfacts(mpt, &facts) != MPT_OK) {
|
||||
device_printf(mpt->dev, "mpt_get_iocfacts failed\n");
|
||||
continue;
|
||||
} else if (mpt->verbose > 1) {
|
||||
}
|
||||
|
||||
if (mpt->verbose > 1) {
|
||||
device_printf(mpt->dev,
|
||||
"mpt_get_iocfacts: GlobalCredits=%d BlockSize=%u "
|
||||
"Request Frame Size %u\n", facts.GlobalCredits,
|
||||
facts.BlockSize, facts.RequestFrameSize);
|
||||
}
|
||||
mpt->mpt_global_credits = facts.GlobalCredits;
|
||||
mpt->blk_size = facts.BlockSize;
|
||||
mpt->request_frame_size = facts.RequestFrameSize;
|
||||
|
||||
if (mpt_get_portfacts(mpt, &pfp) != MPT_OK) {
|
||||
device_printf(mpt->dev, "mpt_get_portfacts failed\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mpt->verbose > 1) {
|
||||
device_printf(mpt->dev,
|
||||
"mpt_get_portfacts: Type %x PFlags %x IID %d\n",
|
||||
pfp.PortType, pfp.ProtocolFlags, pfp.PortSCSIID);
|
||||
}
|
||||
|
||||
if (pfp.PortType != MPI_PORTFACTS_PORTTYPE_SCSI &&
|
||||
pfp.PortType != MPI_PORTFACTS_PORTTYPE_FC) {
|
||||
device_printf(mpt->dev, "Unsupported Port Type (%x)\n",
|
||||
pfp.PortType);
|
||||
return (ENXIO);
|
||||
}
|
||||
if (!(pfp.ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR)) {
|
||||
device_printf(mpt->dev, "initiator role unsupported\n");
|
||||
return (ENXIO);
|
||||
}
|
||||
if (pfp.PortType == MPI_PORTFACTS_PORTTYPE_FC) {
|
||||
mpt->is_fc = 1;
|
||||
} else {
|
||||
mpt->is_fc = 0;
|
||||
}
|
||||
mpt->mpt_ini_id = pfp.PortSCSIID;
|
||||
|
||||
if (mpt_send_ioc_init(mpt, who) != MPT_OK) {
|
||||
device_printf(mpt->dev, "mpt_send_ioc_init failed\n");
|
||||
continue;
|
||||
} else if (mpt->verbose > 1) {
|
||||
}
|
||||
|
||||
if (mpt->verbose > 1) {
|
||||
device_printf(mpt->dev, "mpt_send_ioc_init ok\n");
|
||||
}
|
||||
|
||||
@ -650,7 +1135,8 @@ mpt_init(struct mpt_softc *mpt, u_int32_t who)
|
||||
device_printf(mpt->dev,
|
||||
"IOC failed to go to run state\n");
|
||||
continue;
|
||||
} else if (mpt->verbose > 1) {
|
||||
}
|
||||
if (mpt->verbose > 1) {
|
||||
device_printf(mpt->dev, "IOC now at RUNSTATE\n");
|
||||
}
|
||||
|
||||
@ -667,12 +1153,35 @@ mpt_init(struct mpt_softc *mpt, u_int32_t who)
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable asynchronous event reporting
|
||||
*/
|
||||
mpt_send_event_request(mpt, 1);
|
||||
|
||||
|
||||
/*
|
||||
* Read set up initial configuration information
|
||||
* (SPI only for now)
|
||||
*/
|
||||
|
||||
if (mpt->is_fc == 0) {
|
||||
if (mpt_read_config_info_spi(mpt)) {
|
||||
return (EIO);
|
||||
}
|
||||
if (mpt_set_initial_config_spi(mpt)) {
|
||||
return (EIO);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Now enable the port
|
||||
*/
|
||||
if (mpt_send_port_enable(mpt, 0) != MPT_OK) {
|
||||
device_printf(mpt->dev, "failed to enable port 0\n");
|
||||
continue;
|
||||
} else if (mpt->verbose > 1) {
|
||||
}
|
||||
|
||||
if (mpt->verbose > 1) {
|
||||
device_printf(mpt->dev, "enabled port 0\n");
|
||||
}
|
||||
|
||||
|
@ -145,33 +145,24 @@ enum _MPT_DIAG_BITS {
|
||||
#define MPT_CONTEXT_REPLY (0x80000000)
|
||||
#define MPT_CONTEXT_MASK (~0xE0000000)
|
||||
|
||||
#include "dev/mpt/mpilib/mpi_type.h"
|
||||
#include "dev/mpt/mpilib/mpi.h"
|
||||
#include "dev/mpt/mpilib/mpi_cnfg.h"
|
||||
#include "dev/mpt/mpilib/mpi_fc.h"
|
||||
#include "dev/mpt/mpilib/mpi_init.h"
|
||||
#include "dev/mpt/mpilib/mpi_ioc.h"
|
||||
#include "dev/mpt/mpilib/mpi_lan.h"
|
||||
#include "dev/mpt/mpilib/mpi_targ.h"
|
||||
|
||||
#ifdef _KERNEL
|
||||
int mpt_soft_reset(struct mpt_softc *mpt);
|
||||
void mpt_hard_reset(struct mpt_softc *mpt);
|
||||
int mpt_recv_handshake_reply(struct mpt_softc *mpt, size_t reply_len, void *reply);
|
||||
int mpt_soft_reset(mpt_softc_t *mpt);
|
||||
void mpt_hard_reset(mpt_softc_t *mpt);
|
||||
int mpt_recv_handshake_reply(mpt_softc_t *mpt, size_t reply_len, void *reply);
|
||||
|
||||
|
||||
void mpt_send_cmd(struct mpt_softc *mpt, request_t *req);
|
||||
void mpt_free_reply(struct mpt_softc *mpt, u_int32_t ptr);
|
||||
void mpt_enable_ints(struct mpt_softc *mpt);
|
||||
void mpt_disable_ints(struct mpt_softc *mpt);
|
||||
u_int32_t mpt_pop_reply_queue(struct mpt_softc *mpt);
|
||||
int mpt_init(struct mpt_softc *mpt, u_int32_t who);
|
||||
int mpt_reset(struct mpt_softc *mpt);
|
||||
int mpt_send_handshake_cmd(struct mpt_softc *mpt, size_t len, void *cmd);
|
||||
request_t * mpt_get_request(struct mpt_softc *mpt);
|
||||
void mpt_free_request(struct mpt_softc *mpt, request_t *req);
|
||||
void mpt_send_cmd(mpt_softc_t *mpt, request_t *req);
|
||||
void mpt_free_reply(mpt_softc_t *mpt, u_int32_t ptr);
|
||||
void mpt_enable_ints(mpt_softc_t *mpt);
|
||||
void mpt_disable_ints(mpt_softc_t *mpt);
|
||||
u_int32_t mpt_pop_reply_queue(mpt_softc_t *mpt);
|
||||
int mpt_init(mpt_softc_t *mpt, u_int32_t who);
|
||||
int mpt_reset(mpt_softc_t *mpt);
|
||||
int mpt_send_handshake_cmd(mpt_softc_t *mpt, size_t len, void *cmd);
|
||||
request_t * mpt_get_request(mpt_softc_t *mpt);
|
||||
void mpt_free_request(mpt_softc_t *mpt, request_t *req);
|
||||
int mpt_intr(void *dummy);
|
||||
void mpt_check_doorbell(struct mpt_softc* mpt);
|
||||
void mpt_check_doorbell(mpt_softc_t * mpt);
|
||||
|
||||
/* mpt_debug.c functions */
|
||||
void mpt_print_reply(void *vmsg);
|
||||
@ -182,6 +173,5 @@ char *mpt_req_state(enum mpt_req_state state);
|
||||
void mpt_print_scsi_io_request(MSG_SCSI_IO_REQUEST *msg);
|
||||
void mpt_print_config_request(void *vmsg);
|
||||
void mpt_print_request(void *vmsg);
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif
|
||||
#endif /* _MPT_H_ */
|
||||
|
@ -30,7 +30,7 @@
|
||||
* Additional Copyright (c) 2002 by Matthew Jacob under same license.
|
||||
*/
|
||||
|
||||
#include <dev/mpt/mpt.h>
|
||||
#include <dev/mpt/mpt_freebsd.h>
|
||||
|
||||
struct Error_Map {
|
||||
int Error_Code;
|
||||
@ -324,7 +324,7 @@ mpt_print_ioc_facts(MSG_IOC_FACTS_REPLY *msg)
|
||||
printf("\tFlags %d\n", msg->Flags);
|
||||
printf("\tReplyQueueDepth %d\n", msg->ReplyQueueDepth);
|
||||
printf("\tReqFrameSize 0x%04x\n", msg->RequestFrameSize);
|
||||
printf("\tFW Version 0x%04x\n", msg->FWVersion);
|
||||
printf("\tFW Version 0x%08x\n", msg->FWVersion.Word);
|
||||
printf("\tProduct ID 0x%04x\n", msg->ProductID);
|
||||
printf("\tCredits 0x%04x\n", msg->GlobalCredits);
|
||||
printf("\tPorts %d\n", msg->NumberOfPorts);
|
||||
|
@ -31,20 +31,13 @@
|
||||
*/
|
||||
|
||||
#include <dev/mpt/mpt_freebsd.h>
|
||||
#include <dev/mpt/mpt.h>
|
||||
#include <machine/stdarg.h>
|
||||
#include <sys/signal.h>
|
||||
|
||||
#if 0
|
||||
static void mpt_cam_async(void *, u_int32_t, struct cam_path *, void *);
|
||||
static void mpt_intr_enable(void *);
|
||||
#endif
|
||||
static void mpt_poll(struct cam_sim *);
|
||||
static timeout_t mpttimeout;
|
||||
static void mpt_action(struct cam_sim *, union ccb *);
|
||||
|
||||
void
|
||||
mpt_cam_attach(struct mpt_softc *mpt)
|
||||
mpt_cam_attach(mpt_softc_t *mpt)
|
||||
{
|
||||
struct cam_devq *devq;
|
||||
struct cam_sim *sim;
|
||||
@ -52,7 +45,7 @@ mpt_cam_attach(struct mpt_softc *mpt)
|
||||
|
||||
mpt->bus = 0;
|
||||
maxq = (mpt->mpt_global_credits < MPT_MAX_REQUESTS)?
|
||||
mpt->mpt_global_credits : MPT_MAX_REQUESTS;
|
||||
mpt->mpt_global_credits : MPT_MAX_REQUESTS;
|
||||
|
||||
|
||||
/*
|
||||
@ -74,19 +67,10 @@ mpt_cam_attach(struct mpt_softc *mpt)
|
||||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
mpt->mpt_osinfo.ehook.ich_func = mpt_intr_enable;
|
||||
mpt->mpt_osinfo.ehook.ich_arg = mpt;
|
||||
if (config_intrhook_establish(&mpt->mpt_osinfo.ehook) != 0) {
|
||||
device_printf(mpt->dev,
|
||||
"could not establish interrupt enable hook\n");
|
||||
cam_sim_free(sim, TRUE);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* Register exactly the bus.
|
||||
*/
|
||||
|
||||
/* Register exactly one bus */
|
||||
/* (Duals look like two cards to us) */
|
||||
if (xpt_bus_register(sim, 0) != CAM_SUCCESS) {
|
||||
cam_sim_free(sim, TRUE);
|
||||
return;
|
||||
@ -98,22 +82,11 @@ mpt_cam_attach(struct mpt_softc *mpt)
|
||||
cam_sim_free(sim, TRUE);
|
||||
return;
|
||||
}
|
||||
|
||||
#if 0 /* GJA Don't think we care about lost devices */
|
||||
struct ccb_setasync csa;
|
||||
|
||||
xpt_setup_ccb(&csa.ccb_h, mpt->path, 5);
|
||||
csa.ccb_h.func_code = XPT_SASYNC_CB;
|
||||
csa.event_enable = AC_LOST_DEVICE;
|
||||
csa.callback = mpt_cam_async;
|
||||
csa.callback_arg = sim;
|
||||
xpt_action((union ccb *)&csa);
|
||||
#endif
|
||||
mpt->sim = sim;
|
||||
}
|
||||
|
||||
void
|
||||
mpt_cam_detach(struct mpt_softc *mpt)
|
||||
mpt_cam_detach(mpt_softc_t *mpt)
|
||||
{
|
||||
if (mpt->sim != NULL) {
|
||||
xpt_free_path(mpt->path);
|
||||
@ -123,59 +96,16 @@ mpt_cam_detach(struct mpt_softc *mpt)
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Sample routine for processing async events from CAM */
|
||||
static void
|
||||
mpt_cam_async(void *cbarg, u_int32_t code, struct cam_path *path, void *arg)
|
||||
{
|
||||
struct cam_sim *sim;
|
||||
struct mpt_softc *mpt;
|
||||
|
||||
sim = (struct cam_sim *)cbarg;
|
||||
mpt = (struct mpt_softc *) cam_sim_softc(sim);
|
||||
switch (code) {
|
||||
#if 0 /* GJA */
|
||||
case AC_LOST_DEVICE:
|
||||
if (IS_SCSI(mpt)) {
|
||||
u_int16_t oflags, nflags;
|
||||
sdparam *sdp = mpt->mpt_param;
|
||||
int rvf, tgt;
|
||||
|
||||
tgt = xpt_path_target_id(path);
|
||||
rvf = ISP_FW_REVX(mpt->mpt_fwrev);
|
||||
ISP_LOCK(mpt);
|
||||
sdp += cam_sim_bus(sim);
|
||||
mpt->mpt_update |= (1 << cam_sim_bus(sim));
|
||||
nflags = DPARM_SAFE_DFLT;
|
||||
if (rvf >= ISP_FW_REV(7, 55, 0) ||
|
||||
(ISP_FW_REV(4, 55, 0) <= rvf &&
|
||||
(rvf < ISP_FW_REV(5, 0, 0)))) {
|
||||
nflags |= DPARM_NARROW | DPARM_ASYNC;
|
||||
}
|
||||
oflags = sdp->mpt_devparam[tgt].dev_flags;
|
||||
sdp->mpt_devparam[tgt].dev_flags = nflags;
|
||||
sdp->mpt_devparam[tgt].dev_update = 1;
|
||||
(void) mpt_control(mpt, ISPCTL_UPDATE_PARAMS, NULL);
|
||||
sdp->mpt_devparam[tgt].dev_flags = oflags;
|
||||
ISP_UNLOCK(mpt);
|
||||
}
|
||||
break;
|
||||
#endif /* 0 GJA */
|
||||
default:
|
||||
device_printf(mpt->dev,
|
||||
"mpt Async Code 0x%x\n", code);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* This routine is used after a system crash to dump core onto the
|
||||
* swap device.
|
||||
*/
|
||||
static void
|
||||
mpt_poll(struct cam_sim *sim)
|
||||
{
|
||||
mpt_intr((struct mpt_softc *) cam_sim_softc(sim));
|
||||
mpt_softc_t *mpt = (mpt_softc_t *) cam_sim_softc(sim);
|
||||
MPT_LOCK(mpt);
|
||||
mpt_intr(mpt);
|
||||
MPT_UNLOCK(mpt);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -186,16 +116,17 @@ static void
|
||||
mpttimeout(void *arg)
|
||||
{
|
||||
request_t *req;
|
||||
union ccb *ccb = arg;
|
||||
struct mpt_softc *mpt;
|
||||
union ccb *ccb = arg;
|
||||
mpt_softc_t *mpt;
|
||||
|
||||
mpt = ccb->ccb_h.ccb_mpt_ptr;
|
||||
MPT_LOCK(mpt);
|
||||
|
||||
req = ccb->ccb_h.ccb_req_ptr;
|
||||
|
||||
mpt->timeouts++;
|
||||
|
||||
device_printf(mpt->dev, "time out on request index = 0x%02x sequence = 0x%08x\n",
|
||||
req->index, req->sequence);
|
||||
device_printf(mpt->dev,
|
||||
"time out on request index = 0x%02x sequence = 0x%08x\n",
|
||||
req->index, req->sequence);
|
||||
mpt_check_doorbell(mpt);
|
||||
device_printf(mpt->dev, "Status %08X; Mask %08X; Doorbell %08X\n",
|
||||
mpt_read(mpt, MPT_OFFSET_INTR_STATUS),
|
||||
@ -212,7 +143,9 @@ mpttimeout(void *arg)
|
||||
req->ccb = NULL;
|
||||
ccb->ccb_h.status = CAM_CMD_TIMEOUT;
|
||||
ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
|
||||
MPTLOCK_2_CAMLOCK(mpt);
|
||||
xpt_done(ccb);
|
||||
CAMLOCK_2_MPTLOCK(mpt);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -225,10 +158,9 @@ mpttimeout(void *arg)
|
||||
static void
|
||||
mpt_execute_req(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
|
||||
{
|
||||
int s;
|
||||
request_t *req;
|
||||
union ccb *ccb;
|
||||
struct mpt_softc *mpt;
|
||||
mpt_softc_t *mpt;
|
||||
MSG_SCSI_IO_REQUEST *mpt_req;
|
||||
SGE_SIMPLE32 *se;
|
||||
|
||||
@ -258,7 +190,9 @@ mpt_execute_req(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
|
||||
ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
|
||||
ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
|
||||
xpt_done(ccb);
|
||||
CAMLOCK_2_MPTLOCK(mpt);
|
||||
mpt_free_request(mpt, req);
|
||||
MPTLOCK_2_CAMLOCK(mpt);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -389,18 +323,18 @@ mpt_execute_req(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
|
||||
MPI_SGE_FLAGS_SIMPLE_ELEMENT | MPI_SGE_FLAGS_END_OF_LIST));
|
||||
}
|
||||
|
||||
s = splcam();
|
||||
/*
|
||||
* Last time we need to check if this CCB needs to be aborted.
|
||||
*/
|
||||
if (ccb->ccb_h.status != CAM_REQ_INPROG) {
|
||||
if (nseg && (ccb->ccb_h.flags & CAM_SG_LIST_PHYS) == 0)
|
||||
bus_dmamap_unload(mpt->buffer_dmat, req->dmap);
|
||||
CAMLOCK_2_MPTLOCK(mpt);
|
||||
mpt_free_request(mpt, req);
|
||||
MPTLOCK_2_CAMLOCK(mpt);
|
||||
ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
|
||||
ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
|
||||
xpt_done(ccb);
|
||||
splx(s);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -412,13 +346,11 @@ mpt_execute_req(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
|
||||
} else {
|
||||
callout_handle_init(&ccb->ccb_h.timeout_ch);
|
||||
}
|
||||
|
||||
if (mpt->verbose > 1)
|
||||
mpt_print_scsi_io_request(mpt_req);
|
||||
|
||||
CAMLOCK_2_MPTLOCK(mpt);
|
||||
mpt_send_cmd(mpt, req);
|
||||
|
||||
splx(s);
|
||||
MPTLOCK_2_CAMLOCK(mpt);
|
||||
}
|
||||
|
||||
/* Convert a CAM SCSI I/O ccb into a MPT request to pass the FC Chip */
|
||||
@ -436,9 +368,12 @@ mpt_start(union ccb *ccb)
|
||||
mpt = ccb->ccb_h.ccb_mpt_ptr;
|
||||
|
||||
/* Get a request structure off the free list */
|
||||
CAMLOCK_2_MPTLOCK(mpt);
|
||||
if ((req = mpt_get_request(mpt)) == NULL) {
|
||||
MPTLOCK_2_CAMLOCK(mpt);
|
||||
return (CAM_REQUEUE_REQ);
|
||||
}
|
||||
MPTLOCK_2_CAMLOCK(mpt);
|
||||
|
||||
/* Link the ccb and the request structure so we can find */
|
||||
/* the other knowing either the request or the ccb */
|
||||
@ -580,7 +515,7 @@ mpt_bus_reset(union ccb *ccb)
|
||||
{
|
||||
int error;
|
||||
request_t *req;
|
||||
struct mpt_softc *mpt;
|
||||
mpt_softc_t *mpt;
|
||||
MSG_SCSI_TASK_MGMT *reset_req;
|
||||
|
||||
/* Get the pointer for the physical adapter */
|
||||
@ -630,7 +565,7 @@ mpt_bus_reset(union ccb *ccb)
|
||||
* Process an asynchronous event from the IOC.
|
||||
*/
|
||||
void
|
||||
mpt_notify(struct mpt_softc *mpt, void *vmsg)
|
||||
mpt_notify(mpt_softc_t *mpt, void *vmsg, u_int32_t reply)
|
||||
{
|
||||
MSG_DEFAULT_REPLY *dmsg = vmsg;
|
||||
|
||||
@ -759,6 +694,7 @@ mpt_notify(struct mpt_softc *mpt, void *vmsg)
|
||||
default:
|
||||
device_printf(mpt->dev, "Unknown event %X\n", msg->Event);
|
||||
}
|
||||
mpt_free_reply(mpt, (reply << 1));
|
||||
} else if (dmsg->Function == MPI_FUNCTION_PORT_ENABLE) {
|
||||
MSG_PORT_ENABLE_REPLY *msg = vmsg;
|
||||
int index = msg->MsgContext & ~0x80000000;
|
||||
@ -770,6 +706,17 @@ mpt_notify(struct mpt_softc *mpt, void *vmsg)
|
||||
request_t *req = &mpt->requests[index];
|
||||
req->debug = REQ_DONE;
|
||||
}
|
||||
mpt_free_reply(mpt, (reply << 1));
|
||||
} else if (dmsg->Function == MPI_FUNCTION_CONFIG) {
|
||||
MSG_CONFIG_REPLY *msg = vmsg;
|
||||
int index = msg->MsgContext & ~0x80000000;
|
||||
if (index >= 0 && index < MPT_MAX_REQUESTS) {
|
||||
request_t *req = &mpt->requests[index];
|
||||
req->debug = REQ_DONE;
|
||||
req->sequence = reply;
|
||||
} else {
|
||||
mpt_free_reply(mpt, (reply << 1));
|
||||
}
|
||||
} else {
|
||||
device_printf(mpt->dev, "unknown mpt_notify: %x\n",
|
||||
dmsg->Function);
|
||||
@ -777,7 +724,7 @@ mpt_notify(struct mpt_softc *mpt, void *vmsg)
|
||||
}
|
||||
|
||||
void
|
||||
mpt_done(struct mpt_softc *mpt, u_int32_t reply)
|
||||
mpt_done(mpt_softc_t *mpt, u_int32_t reply)
|
||||
{
|
||||
int index;
|
||||
request_t *req;
|
||||
@ -817,8 +764,7 @@ mpt_done(struct mpt_softc *mpt, u_int32_t reply)
|
||||
/* to process it then free it */
|
||||
if ((index & 0x80000000) != 0) {
|
||||
if (mpt_reply != NULL) {
|
||||
mpt_notify(mpt, mpt_reply);
|
||||
mpt_free_reply(mpt, (reply << 1));
|
||||
mpt_notify(mpt, mpt_reply, reply);
|
||||
} else {
|
||||
device_printf(mpt->dev,
|
||||
"mpt_done: index 0x%x, NULL reply\n", index);
|
||||
@ -1016,7 +962,9 @@ mpt_done(struct mpt_softc *mpt, u_int32_t reply)
|
||||
if ((mpt_reply->MsgFlags & 0x80) == 0)
|
||||
ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
|
||||
ccb->ccb_h.status &= ~CAM_SIM_QUEUED;
|
||||
MPTLOCK_2_CAMLOCK(mpt);
|
||||
xpt_done(ccb);
|
||||
CAMLOCK_2_MPTLOCK(mpt);
|
||||
|
||||
done:
|
||||
/* If IOC done with this request free it up */
|
||||
@ -1032,12 +980,12 @@ static void
|
||||
mpt_action(struct cam_sim *sim, union ccb *ccb)
|
||||
{
|
||||
int tgt, error;
|
||||
struct mpt_softc *mpt;
|
||||
mpt_softc_t *mpt;
|
||||
struct ccb_trans_settings *cts;
|
||||
|
||||
CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("mpt_action\n"));
|
||||
|
||||
mpt = (struct mpt_softc *)cam_sim_softc(sim);
|
||||
mpt = (mpt_softc_t *)cam_sim_softc(sim);
|
||||
|
||||
ccb->ccb_h.ccb_mpt_ptr = mpt;
|
||||
|
||||
@ -1045,16 +993,15 @@ mpt_action(struct cam_sim *sim, union ccb *ccb)
|
||||
case XPT_RESET_BUS:
|
||||
if (mpt->verbose > 1)
|
||||
device_printf(mpt->dev, "XPT_RESET_BUS\n");
|
||||
CAMLOCK_2_MPTLOCK(mpt);
|
||||
error = mpt_bus_reset(ccb);
|
||||
MPTLOCK_2_CAMLOCK(mpt);
|
||||
switch (error) {
|
||||
case CAM_REQ_INPROG:
|
||||
ccb->ccb_h.status |= CAM_SIM_QUEUED;
|
||||
break;
|
||||
case CAM_REQUEUE_REQ:
|
||||
/* if (mpt->mpt_osinfo.simqfrozen == 0) */
|
||||
{
|
||||
xpt_freeze_simq(sim, 1);
|
||||
}
|
||||
xpt_freeze_simq(sim, 1);
|
||||
ccb->ccb_h.status = CAM_REQUEUE_REQ;
|
||||
xpt_done(ccb);
|
||||
break;
|
||||
@ -1090,20 +1037,14 @@ mpt_action(struct cam_sim *sim, union ccb *ccb)
|
||||
}
|
||||
|
||||
ccb->csio.scsi_status = SCSI_STATUS_OK;
|
||||
/* XXX GJA MPT_LOCK(mpt); */
|
||||
error = mpt_start(ccb);
|
||||
/* XXX GJA MPT_UNLOCK(mpt); */
|
||||
switch (error) {
|
||||
case CAM_REQ_INPROG:
|
||||
ccb->ccb_h.status |= CAM_SIM_QUEUED;
|
||||
break;
|
||||
|
||||
case CAM_REQUEUE_REQ:
|
||||
/* if (mpt->mpt_osinfo.simqfrozen == 0) */
|
||||
{
|
||||
xpt_freeze_simq(sim, 1);
|
||||
}
|
||||
/* mpt->mpt_osinfo.simqfrozen |= SIMQFRZ_RESOURCE; */
|
||||
xpt_freeze_simq(sim, 1);
|
||||
ccb->ccb_h.status = CAM_REQUEUE_REQ;
|
||||
xpt_done(ccb);
|
||||
break;
|
||||
@ -1114,21 +1055,36 @@ mpt_action(struct cam_sim *sim, union ccb *ccb)
|
||||
break;
|
||||
|
||||
default:
|
||||
device_printf(mpt->dev, "What's this? 0x%x at %d in file %s\n",
|
||||
error, __LINE__, __FILE__);
|
||||
ccb->ccb_h.status = CAM_REQ_CMP_ERR;
|
||||
xpt_done(ccb);
|
||||
}
|
||||
break;
|
||||
|
||||
case XPT_ABORT:
|
||||
/* Probably ought to impliment this but no one actualy */
|
||||
/* uses it for anything worthwile. XXX GJA */
|
||||
/*
|
||||
* XXX: Need to implement
|
||||
*/
|
||||
ccb->ccb_h.status = CAM_UA_ABORT;
|
||||
xpt_done(ccb);
|
||||
break;
|
||||
|
||||
|
||||
#ifdef CAM_NEW_TRAN_CODE
|
||||
#define IS_CURRENT_SETTINGS(c) (c->type == CTS_TYPE_CURRENT_SETTINGS)
|
||||
#else
|
||||
#define IS_CURRENT_SETTINGS(c) (c->flags & CCB_TRANS_CURRENT_SETTINGS)
|
||||
#endif
|
||||
#define DP_DISC 0x1
|
||||
#define DP_TQING 0x2
|
||||
#define DP_WIDE 0x4
|
||||
|
||||
case XPT_SET_TRAN_SETTINGS: /* Nexus Settings */
|
||||
cts = &ccb->cts;
|
||||
if (!IS_CURRENT_SETTINGS(cts)) {
|
||||
ccb->ccb_h.status = CAM_REQ_INVALID;
|
||||
xpt_done(ccb);
|
||||
break;
|
||||
}
|
||||
/* XXX: need to implement */
|
||||
ccb->ccb_h.status = CAM_REQ_CMP;
|
||||
xpt_done(ccb);
|
||||
break;
|
||||
@ -1136,19 +1092,136 @@ mpt_action(struct cam_sim *sim, union ccb *ccb)
|
||||
case XPT_GET_TRAN_SETTINGS:
|
||||
cts = &ccb->cts;
|
||||
tgt = cts->ccb_h.target_id;
|
||||
/*
|
||||
* a lot of normal SCSI things don't make sense.
|
||||
*/
|
||||
cts->flags = CCB_TRANS_TAG_ENB | CCB_TRANS_DISC_ENB;
|
||||
cts->valid = CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID;
|
||||
/*
|
||||
* How do you measure the width of a high
|
||||
* speed serial bus? Well, in bytes.
|
||||
*
|
||||
* Offset and period make no sense, though, so we set
|
||||
* (above) a 'base' transfer speed to be gigabit.
|
||||
*/
|
||||
cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
|
||||
if (mpt->is_fc) {
|
||||
#ifndef CAM_NEW_TRAN_CODE
|
||||
/*
|
||||
* a lot of normal SCSI things don't make sense.
|
||||
*/
|
||||
cts->flags = CCB_TRANS_TAG_ENB | CCB_TRANS_DISC_ENB;
|
||||
cts->valid = CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID;
|
||||
/*
|
||||
* How do you measure the width of a high
|
||||
* speed serial bus? Well, in bytes.
|
||||
*
|
||||
* Offset and period make no sense, though, so we set
|
||||
* (above) a 'base' transfer speed to be gigabit.
|
||||
*/
|
||||
cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
|
||||
#else
|
||||
struct ccb_trans_settings_fc *fc =
|
||||
&cts->xport_specific.fc;
|
||||
|
||||
cts->protocol = PROTO_SCSI;
|
||||
cts->protocol_version = SCSI_REV_2;
|
||||
cts->transport = XPORT_FC;
|
||||
cts->transport_version = 0;
|
||||
|
||||
fc->valid = CTS_FC_VALID_SPEED;
|
||||
fc->bitrate = 100000; /* XXX: Need for 2Gb/s */
|
||||
/* XXX: need a port database for each target */
|
||||
#endif
|
||||
} else {
|
||||
#ifdef CAM_NEW_TRAN_CODE
|
||||
struct ccb_trans_settings_scsi *scsi =
|
||||
&cts->proto_specific.scsi;
|
||||
struct ccb_trans_settings_spi *spi =
|
||||
&cts->xport_specific.spi;
|
||||
#endif
|
||||
u_int8_t dval, pval, oval;
|
||||
|
||||
if (IS_CURRENT_SETTINGS(cts)) {
|
||||
dval = 0;
|
||||
if (mpt->mpt_dev_page0[tgt].
|
||||
NegotiatedParameters &
|
||||
MPI_SCSIDEVPAGE0_NP_WIDE)
|
||||
dval |= DP_WIDE;
|
||||
|
||||
if (mpt->mpt_port_page2.DeviceSettings[tgt].
|
||||
DeviceFlags &
|
||||
MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE)
|
||||
dval |= DP_DISC;
|
||||
|
||||
if (mpt->mpt_port_page2.DeviceSettings[tgt].
|
||||
DeviceFlags &
|
||||
MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE)
|
||||
dval |= DP_TQING;
|
||||
|
||||
oval = (mpt->mpt_dev_page0[tgt].
|
||||
NegotiatedParameters >> 16);
|
||||
pval = (mpt->mpt_dev_page0[tgt].
|
||||
NegotiatedParameters >> 8);
|
||||
} else {
|
||||
/*
|
||||
* XXX: Fix wrt NVRAM someday. Attempts
|
||||
* XXX: to read port page2 device data
|
||||
* XXX: just returns zero in these areas.
|
||||
*/
|
||||
dval = DP_WIDE|DP_DISC|DP_TQING;
|
||||
oval = (mpt->mpt_port_page0.Capabilities >> 16);
|
||||
pval = (mpt->mpt_port_page0.Capabilities >> 8);
|
||||
}
|
||||
#ifndef CAM_NEW_TRAN_CODE
|
||||
cts->flags &= ~(CCB_TRANS_DISC_ENB|CCB_TRANS_TAG_ENB);
|
||||
if (dval & DP_DISC) {
|
||||
cts->flags |= CCB_TRANS_DISC_ENB;
|
||||
}
|
||||
if (dval & DP_TQING) {
|
||||
cts->flags |= CCB_TRANS_TAG_ENB;
|
||||
}
|
||||
if (dval & DP_WIDE) {
|
||||
cts->bus_width = MSG_EXT_WDTR_BUS_16_BIT;
|
||||
} else {
|
||||
cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
|
||||
}
|
||||
cts->valid = CCB_TRANS_BUS_WIDTH_VALID |
|
||||
CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID;
|
||||
if (oval) {
|
||||
cts->sync_period = pval;
|
||||
cts->sync_offset = oval;
|
||||
cts->valid |=
|
||||
CCB_TRANS_SYNC_RATE_VALID |
|
||||
CCB_TRANS_SYNC_OFFSET_VALID;
|
||||
}
|
||||
#else
|
||||
cts->protocol = PROTO_SCSI;
|
||||
cts->protocol_version = SCSI_REV_2;
|
||||
cts->transport = XPORT_SPI;
|
||||
cts->transport_version = 2;
|
||||
|
||||
scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
|
||||
spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
|
||||
if (dval & DP_DISC) {
|
||||
spi->flags |= CTS_SPI_FLAGS_DISC_ENB;
|
||||
}
|
||||
if (dval & DP_TQING) {
|
||||
scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
|
||||
}
|
||||
if (oval && pval) {
|
||||
spi->sync_offset = oval;
|
||||
spi->sync_period = pval;
|
||||
spi->valid |= CTS_SPI_VALID_SYNC_OFFSET;
|
||||
spi->valid |= CTS_SPI_VALID_SYNC_RATE;
|
||||
}
|
||||
spi->valid |= CTS_SPI_VALID_BUS_WIDTH;
|
||||
if (dval & DP_WIDE) {
|
||||
spi->bus_width = MSG_EXT_WDTR_BUS_16_BIT;
|
||||
} else {
|
||||
spi->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
|
||||
}
|
||||
if (cts->ccb_h.target_lun != CAM_LUN_WILDCARD) {
|
||||
scsi->valid = CTS_SCSI_VALID_TQ;
|
||||
spi->valid |= CTS_SPI_VALID_DISC;
|
||||
} else {
|
||||
scsi->valid = 0;
|
||||
}
|
||||
#endif
|
||||
if (mpt->verbose > 1) {
|
||||
device_printf(mpt->dev,
|
||||
"GET %s targ %d flags %x off %x per %x\n",
|
||||
IS_CURRENT_SETTINGS(cts)? "ACTIVE" :
|
||||
"NVRAM", tgt, dval, oval, pval);
|
||||
}
|
||||
}
|
||||
ccb->ccb_h.status = CAM_REQ_CMP;
|
||||
xpt_done(ccb);
|
||||
break;
|
||||
@ -1161,10 +1234,6 @@ mpt_action(struct cam_sim *sim, union ccb *ccb)
|
||||
|
||||
ccg = &ccb->ccg;
|
||||
if (ccg->block_size == 0) {
|
||||
device_printf(mpt->dev, "%d.%d XPT_CALC_GEOMETRY block size 0?\n",
|
||||
ccg->ccb_h.target_id,
|
||||
ccg->ccb_h.target_lun);
|
||||
|
||||
ccb->ccb_h.status = CAM_REQ_INVALID;
|
||||
xpt_done(ccb);
|
||||
break;
|
||||
@ -1200,7 +1269,7 @@ mpt_action(struct cam_sim *sim, union ccb *ccb)
|
||||
cpi->base_transfer_speed = 100000;
|
||||
cpi->hba_inquiry = PI_TAG_ABLE;
|
||||
} else {
|
||||
cpi->initiator_id = 7; /* XXX */
|
||||
cpi->initiator_id = mpt->mpt_ini_id;
|
||||
cpi->base_transfer_speed = 3300;
|
||||
cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE|PI_WIDE_16;
|
||||
cpi->hba_misc = 0;
|
||||
|
@ -31,15 +31,22 @@
|
||||
|
||||
#ifndef _MPT_FREEBSD_H_
|
||||
#define _MPT_FREEBSD_H_
|
||||
#include <sys/ioccom.h>
|
||||
|
||||
#ifdef _KERNEL
|
||||
/* #define RELENG_4 1 */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/endian.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/queue.h>
|
||||
#ifdef RELENG_4
|
||||
#include <sys/malloc.h>
|
||||
#else
|
||||
#include <sys/lock.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/condvar.h>
|
||||
#endif
|
||||
#include <sys/proc.h>
|
||||
#include <sys/bus.h>
|
||||
|
||||
@ -58,9 +65,50 @@
|
||||
#include <cam/cam_debug.h>
|
||||
#include <cam/scsi/scsi_all.h>
|
||||
#include <cam/scsi/scsi_message.h>
|
||||
|
||||
#include "opt_ddb.h"
|
||||
|
||||
#include "dev/mpt/mpilib/mpi_type.h"
|
||||
#include "dev/mpt/mpilib/mpi.h"
|
||||
#include "dev/mpt/mpilib/mpi_cnfg.h"
|
||||
#include "dev/mpt/mpilib/mpi_fc.h"
|
||||
#include "dev/mpt/mpilib/mpi_init.h"
|
||||
#include "dev/mpt/mpilib/mpi_ioc.h"
|
||||
#include "dev/mpt/mpilib/mpi_lan.h"
|
||||
#include "dev/mpt/mpilib/mpi_targ.h"
|
||||
|
||||
|
||||
#define INLINE __inline
|
||||
|
||||
#ifdef RELENG_4
|
||||
#define MPT_IFLAGS INTR_TYPE_CAM
|
||||
#define MPT_LOCK(mpt) mpt_lockspl(mpt)
|
||||
#define MPT_UNLOCK(mpt) mpt_unlockspl(mpt)
|
||||
#define MPTLOCK_2_CAMLOCK MPT_UNLOCK
|
||||
#define CAMLOCK_2_MPTLOCK(mpt) MPT_LOCK
|
||||
#define MPT_LOCK_SETUP(mpt)
|
||||
#define MPT_LOCK_DESTROY(mpt)
|
||||
#else
|
||||
#define MPT_IFLAGS INTR_TYPE_CAM | INTR_ENTROPY | INTR_MPSAFE
|
||||
#define MPT_LOCK_SETUP(mpt) \
|
||||
mtx_init(&mpt->mpt_lock, "mpt", NULL, MTX_DEF); \
|
||||
mpt->mpt_locksetup = 1
|
||||
#define MPT_LOCK_DESTROY(mpt) \
|
||||
if (mpt->mpt_locksetup) { \
|
||||
mtx_destroy(&mpt->mpt_lock); \
|
||||
mpt->mpt_locksetup = 0; \
|
||||
}
|
||||
|
||||
#define MPT_LOCK(mpt) mtx_lock(&(mpt)->mpt_lock)
|
||||
#define MPT_UNLOCK(mpt) mtx_unlock(&(mpt)->mpt_lock)
|
||||
#define MPTLOCK_2_CAMLOCK(mpt) \
|
||||
mtx_unlock(&(mpt)->mpt_lock); mtx_lock(&Giant)
|
||||
#define CAMLOCK_2_MPTLOCK(mpt) \
|
||||
mtx_unlock(&Giant); mtx_lock(&(mpt)->mpt_lock)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Max MPT Reply we are willing to accept (must be power of 2) */
|
||||
#define MPT_REPLY_SIZE 128
|
||||
|
||||
@ -112,17 +160,16 @@ enum mpt_req_state {
|
||||
REQ_FREE, REQ_IN_PROGRESS, REQ_TIMEOUT, REQ_ON_CHIP, REQ_DONE
|
||||
};
|
||||
typedef struct req_entry {
|
||||
u_int16_t index; /* Index of this entry */
|
||||
union ccb *ccb; /* Request that generated this command */
|
||||
void *req_vbuf; /* Virtual Address of Entry */
|
||||
void *sense_vbuf; /* Virtual Address of sense data */
|
||||
u_int32_t req_pbuf; /* Physical Address of Entry */
|
||||
u_int32_t sense_pbuf; /* Physical Address of sense data */
|
||||
bus_dmamap_t dmap; /* DMA map for data buffer */
|
||||
SLIST_ENTRY(req_entry) link; /* Pointer to next in list */
|
||||
enum mpt_req_state debug; /* Debuging */
|
||||
u_int32_t sequence; /* Sequence Number */
|
||||
|
||||
u_int16_t index; /* Index of this entry */
|
||||
union ccb *ccb; /* CAM request */
|
||||
void *req_vbuf; /* Virtual Address of Entry */
|
||||
void *sense_vbuf; /* Virtual Address of sense data */
|
||||
u_int32_t req_pbuf; /* Physical Address of Entry */
|
||||
u_int32_t sense_pbuf; /* Physical Address of sense data */
|
||||
bus_dmamap_t dmap; /* DMA map for data buffer */
|
||||
SLIST_ENTRY(req_entry) link; /* Pointer to next in list */
|
||||
enum mpt_req_state debug; /* Debugging */
|
||||
u_int32_t sequence; /* Sequence Number */
|
||||
} request_t;
|
||||
|
||||
|
||||
@ -138,98 +185,162 @@ struct mpt_pci_cfg {
|
||||
u_int32_t PMCSR;
|
||||
};
|
||||
|
||||
struct mpt_softc {
|
||||
device_t dev;
|
||||
int unit;
|
||||
struct mtx lock;
|
||||
|
||||
/* Operational flags, set during initialization */
|
||||
int verbose; /* print debug messages */
|
||||
|
||||
struct resource *pci_irq; /* Interrupt map for chip */
|
||||
void *ih; /* Interupt handle */
|
||||
|
||||
/* First Memory Region (Device MEM) */
|
||||
struct resource *pci_reg; /* Register map for chip */
|
||||
int pci_reg_id; /* Resource ID */
|
||||
bus_space_tag_t pci_st; /* Bus tag for registers */
|
||||
bus_space_handle_t pci_sh; /* Bus handle for registers */
|
||||
vm_offset_t pci_pa; /* Physical Address */
|
||||
|
||||
/* Second Memory Region (Diagnostic memory window) */
|
||||
/* (only used for diagnostic purposes) */
|
||||
struct resource *pci_mem; /* Register map for chip */
|
||||
int pci_mem_id; /* Resource ID */
|
||||
bus_space_tag_t pci_mst; /* Bus tag for registers */
|
||||
bus_space_handle_t pci_msh; /* Bus handle for registers */
|
||||
|
||||
/* DMA Memory for IOCTLs */
|
||||
void *ioctl_mem_va; /* Virtual Addr */
|
||||
u_int32_t ioctl_mem_pa; /* Physical Addr */
|
||||
bus_dmamap_t ioctl_mem_map; /* DMA map for buffer */
|
||||
bus_dma_tag_t ioctl_mem_tag; /* DMA tag for memory alloc */
|
||||
int open; /* only allow one open at a time */
|
||||
|
||||
bus_dma_tag_t parent_dmat; /* DMA tag for parent PCI bus */
|
||||
|
||||
bus_dma_tag_t reply_dmat; /* DMA tag for reply memory */
|
||||
bus_dmamap_t reply_dmap; /* DMA map for reply memory */
|
||||
char *reply; /* Virtual address of reply memory */
|
||||
u_int32_t reply_phys; /* Physical address of reply memory */
|
||||
|
||||
u_int32_t
|
||||
: 29,
|
||||
typedef struct mpt_softc {
|
||||
device_t dev;
|
||||
#ifdef RELENG_4
|
||||
int mpt_splsaved;
|
||||
u_int32_t mpt_islocked;
|
||||
#else
|
||||
struct mtx mpt_lock;
|
||||
#endif
|
||||
u_int32_t : 16,
|
||||
unit : 8,
|
||||
verbose : 3,
|
||||
: 1,
|
||||
mpt_locksetup : 1,
|
||||
disabled : 1,
|
||||
is_fc : 1,
|
||||
bus : 1; /* FC929/1030 have two busses */
|
||||
|
||||
u_int32_t blk_size; /* Block size transfers to IOC */
|
||||
u_int16_t mpt_global_credits;
|
||||
u_int16_t request_frame_size;
|
||||
/*
|
||||
* IOC Facts
|
||||
*/
|
||||
u_int16_t mpt_global_credits;
|
||||
u_int16_t request_frame_size;
|
||||
u_int8_t mpt_max_devices;
|
||||
u_int8_t mpt_max_buses;
|
||||
|
||||
bus_dma_tag_t buffer_dmat; /* DMA tag for mapping data buffers */
|
||||
/*
|
||||
* Port Facts
|
||||
*/
|
||||
u_int16_t mpt_ini_id;
|
||||
|
||||
bus_dma_tag_t request_dmat; /* DMA tag for request memroy */
|
||||
bus_dmamap_t request_dmap; /* DMA map for request memroy */
|
||||
char *request; /* Virtual address of Request memory */
|
||||
u_int32_t request_phys; /* Physical address of Request memory */
|
||||
|
||||
request_t requests[MPT_MAX_REQUESTS];
|
||||
/*
|
||||
* Device Configuration Information
|
||||
*/
|
||||
union {
|
||||
struct mpt_spi_cfg {
|
||||
fCONFIG_PAGE_SCSI_PORT_0 _port_page0;
|
||||
fCONFIG_PAGE_SCSI_PORT_1 _port_page1;
|
||||
fCONFIG_PAGE_SCSI_PORT_2 _port_page2;
|
||||
fCONFIG_PAGE_SCSI_DEVICE_0 _dev_page0[16];
|
||||
fCONFIG_PAGE_SCSI_DEVICE_1 _dev_page1[16];
|
||||
uint16_t _tagmask;
|
||||
uint16_t _update_params0;
|
||||
uint16_t _update_params1;
|
||||
} spi;
|
||||
#define mpt_port_page0 cfg.spi._port_page0
|
||||
#define mpt_port_page1 cfg.spi._port_page1
|
||||
#define mpt_port_page2 cfg.spi._port_page2
|
||||
#define mpt_dev_page0 cfg.spi._dev_page0
|
||||
#define mpt_dev_page1 cfg.spi._dev_page1
|
||||
#define mpt_tagmask cfg.spi._tagmask
|
||||
#define mpt_update_params0 cfg.spi._update_params0
|
||||
#define mpt_update_params1 cfg.spi._update_params1
|
||||
struct mpi_fc_cfg {
|
||||
u_int8_t nada;
|
||||
} fc;
|
||||
} cfg;
|
||||
|
||||
/*
|
||||
* PCI Hardware info
|
||||
*/
|
||||
struct resource * pci_irq; /* Interrupt map for chip */
|
||||
void * ih; /* Interupt handle */
|
||||
struct mpt_pci_cfg pci_cfg; /* saved PCI conf registers */
|
||||
|
||||
/*
|
||||
* DMA Mapping Stuff
|
||||
*/
|
||||
|
||||
struct resource * pci_reg; /* Register map for chip */
|
||||
int pci_reg_id; /* Resource ID */
|
||||
bus_space_tag_t pci_st; /* Bus tag for registers */
|
||||
bus_space_handle_t pci_sh; /* Bus handle for registers */
|
||||
vm_offset_t pci_pa; /* Physical Address */
|
||||
|
||||
bus_dma_tag_t parent_dmat; /* DMA tag for parent PCI bus */
|
||||
bus_dma_tag_t reply_dmat; /* DMA tag for reply memory */
|
||||
bus_dmamap_t reply_dmap; /* DMA map for reply memory */
|
||||
char * reply; /* KVA of reply memory */
|
||||
u_int32_t reply_phys; /* BusAddr of reply memory (XXX Wrong) */
|
||||
|
||||
|
||||
bus_dma_tag_t buffer_dmat; /* DMA tag for buffers */
|
||||
bus_dma_tag_t request_dmat; /* DMA tag for request memroy */
|
||||
bus_dmamap_t request_dmap; /* DMA map for request memroy */
|
||||
char * request; /* KVA of Request memory */
|
||||
u_int32_t request_phys; /* BusADdr of request memory (XXX WRONG) */
|
||||
|
||||
|
||||
/*
|
||||
* CAM && Software Management
|
||||
*/
|
||||
|
||||
request_t requests[MPT_MAX_REQUESTS];
|
||||
SLIST_HEAD(req_queue, req_entry) request_free_list;
|
||||
|
||||
struct cam_sim *sim;
|
||||
struct cam_path *path;
|
||||
struct cam_sim * sim;
|
||||
struct cam_path * path;
|
||||
|
||||
u_int32_t sequence; /* Sequence Number */
|
||||
u_int32_t timeouts; /* timeout count */
|
||||
u_int32_t success; /* timeout successes afer timeout */
|
||||
u_int32_t sequence; /* Sequence Number */
|
||||
u_int32_t timeouts; /* timeout count */
|
||||
u_int32_t success; /* successes afer timeout */
|
||||
|
||||
/* Opposing port in a 929, or NULL */
|
||||
struct mpt_softc *mpt2;
|
||||
/* Opposing port in a 929 or 1030, or NULL */
|
||||
struct mpt_softc * mpt2;
|
||||
|
||||
/* Saved values for the PCI configuration registers */
|
||||
struct mpt_pci_cfg pci_cfg;
|
||||
};
|
||||
} mpt_softc_t;
|
||||
|
||||
#include <dev/mpt/mpt.h>
|
||||
|
||||
|
||||
static INLINE void mpt_write(mpt_softc_t *, size_t, u_int32_t);
|
||||
static INLINE u_int32_t mpt_read(mpt_softc_t *, int);
|
||||
|
||||
static INLINE void
|
||||
mpt_write(struct mpt_softc *mpt, size_t offset, u_int32_t val)
|
||||
mpt_write(mpt_softc_t *mpt, size_t offset, u_int32_t val)
|
||||
{
|
||||
bus_space_write_4(mpt->pci_st, mpt->pci_sh, offset, val);
|
||||
}
|
||||
|
||||
static INLINE u_int32_t
|
||||
mpt_read(struct mpt_softc *mpt, int offset)
|
||||
mpt_read(mpt_softc_t *mpt, int offset)
|
||||
{
|
||||
return bus_space_read_4(mpt->pci_st, mpt->pci_sh, offset);
|
||||
return (bus_space_read_4(mpt->pci_st, mpt->pci_sh, offset));
|
||||
}
|
||||
|
||||
void mpt_cam_attach(struct mpt_softc *mpt);
|
||||
void mpt_cam_detach(struct mpt_softc *mpt);
|
||||
void mpt_done(struct mpt_softc *mpt, u_int32_t reply);
|
||||
void mpt_notify(struct mpt_softc *mpt, void *vmsg);
|
||||
void mpt_cam_attach(mpt_softc_t *);
|
||||
void mpt_cam_detach(mpt_softc_t *);
|
||||
void mpt_done(mpt_softc_t *, u_int32_t);
|
||||
void mpt_notify(mpt_softc_t *, void *, u_int32_t);
|
||||
void mpt_set_config_regs(mpt_softc_t *);
|
||||
|
||||
/* mpt_pci.c declarations */
|
||||
void mpt_set_config_regs(struct mpt_softc *mpt);
|
||||
#ifdef RELENG_4
|
||||
static INLINE void mpt_lockspl(mpt_softc_t *);
|
||||
static INLINE void mpt_unlockspl(mpt_softc_t *);
|
||||
|
||||
static INLINE void
|
||||
mpt_lockspl(mpt_softc_t *mpt)
|
||||
{
|
||||
int s = splcam();
|
||||
if (mpt->mpt_islocked++ == 0) {
|
||||
mpt->mpt_splsaved = s;
|
||||
} else {
|
||||
splx(s);
|
||||
}
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
mpt_unlockspl(mpt_softc_t *mpt)
|
||||
{
|
||||
if (mpt->mpt_islocked) {
|
||||
if (--mpt->mpt_islocked == 0) {
|
||||
splx(mpt->mpt_splsaved);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_KERNEL */
|
||||
#endif /* _MPT_FREEBSD_H */
|
||||
|
@ -34,11 +34,9 @@
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/bus.h>
|
||||
|
||||
#include <pci/pcireg.h>
|
||||
#include <pci/pcivar.h>
|
||||
|
||||
@ -47,8 +45,8 @@
|
||||
#include <machine/bus.h>
|
||||
#include <machine/resource.h>
|
||||
#include <sys/rman.h>
|
||||
#include <sys/malloc.h>
|
||||
|
||||
#include <dev/mpt/mpt.h>
|
||||
#include <dev/mpt/mpt_freebsd.h>
|
||||
|
||||
#ifndef PCI_VENDOR_LSI
|
||||
@ -74,12 +72,13 @@
|
||||
|
||||
static int mpt_probe(device_t);
|
||||
static int mpt_attach(device_t);
|
||||
static void mpt_free_bus_resources(struct mpt_softc *mpt);
|
||||
static void mpt_free_bus_resources(mpt_softc_t *mpt);
|
||||
static int mpt_detach(device_t);
|
||||
static int mpt_shutdown(device_t);
|
||||
static int mpt_dma_mem_alloc(struct mpt_softc *mpt);
|
||||
static void mpt_dma_mem_free(struct mpt_softc *mpt);
|
||||
static void mpt_read_config_regs(struct mpt_softc *mpt);
|
||||
static int mpt_dma_mem_alloc(mpt_softc_t *mpt);
|
||||
static void mpt_dma_mem_free(mpt_softc_t *mpt);
|
||||
static void mpt_read_config_regs(mpt_softc_t *mpt);
|
||||
static void mpt_pci_intr(void *);
|
||||
|
||||
static device_method_t mpt_methods[] = {
|
||||
/* Device interface */
|
||||
@ -91,7 +90,7 @@ static device_method_t mpt_methods[] = {
|
||||
};
|
||||
|
||||
static driver_t mpt_driver = {
|
||||
"mpt", mpt_methods, sizeof (struct mpt_softc)
|
||||
"mpt", mpt_methods, sizeof (mpt_softc_t)
|
||||
};
|
||||
static devclass_t mpt_devclass;
|
||||
DRIVER_MODULE(mpt, pci, mpt_driver, mpt_devclass, 0, 0);
|
||||
@ -101,7 +100,7 @@ int
|
||||
mpt_intr(void *dummy)
|
||||
{
|
||||
u_int32_t reply;
|
||||
struct mpt_softc *mpt = (struct mpt_softc *)dummy;
|
||||
mpt_softc_t *mpt = (mpt_softc_t *)dummy;
|
||||
|
||||
reply = mpt_pop_reply_queue(mpt);
|
||||
while (reply != MPT_REPLY_EMPTY) {
|
||||
@ -149,7 +148,7 @@ mpt_probe(device_t dev)
|
||||
|
||||
#ifdef RELENG_4
|
||||
static void
|
||||
mpt_set_options(struct mpt_softc *mpt)
|
||||
mpt_set_options(mpt_softc_t *mpt)
|
||||
{
|
||||
int bitmap;
|
||||
|
||||
@ -171,7 +170,7 @@ mpt_set_options(struct mpt_softc *mpt)
|
||||
}
|
||||
#else
|
||||
static void
|
||||
mpt_set_options(struct mpt_softc *mpt)
|
||||
mpt_set_options(mpt_softc_t *mpt)
|
||||
{
|
||||
int tval;
|
||||
|
||||
@ -194,15 +193,15 @@ mpt_attach(device_t dev)
|
||||
{
|
||||
int iqd;
|
||||
u_int32_t data, cmd;
|
||||
struct mpt_softc *mpt;
|
||||
mpt_softc_t *mpt;
|
||||
|
||||
/* Allocate the softc structure */
|
||||
mpt = (struct mpt_softc*) device_get_softc(dev);
|
||||
mpt = (mpt_softc_t*) device_get_softc(dev);
|
||||
if (mpt == NULL) {
|
||||
device_printf(dev, "cannot allocate softc\n");
|
||||
return (ENOMEM);
|
||||
}
|
||||
bzero(mpt, sizeof (struct mpt_softc));
|
||||
bzero(mpt, sizeof (mpt_softc_t));
|
||||
switch ((pci_get_device(dev) & ~1)) {
|
||||
case PCI_PRODUCT_LSI_FC909:
|
||||
case PCI_PRODUCT_LSI_FC929:
|
||||
@ -243,7 +242,7 @@ mpt_attach(device_t dev)
|
||||
if ((pci_get_device(dev) & ~1) == PCI_PRODUCT_LSI_FC929) {
|
||||
/* Yes; is the previous device the counterpart? */
|
||||
if (mpt->unit) {
|
||||
mpt->mpt2 = (struct mpt_softc *)
|
||||
mpt->mpt2 = (mpt_softc_t *)
|
||||
devclass_get_softc(mpt_devclass, mpt->unit-1);
|
||||
|
||||
if ((mpt->mpt2->mpt2 == NULL)
|
||||
@ -285,13 +284,14 @@ mpt_attach(device_t dev)
|
||||
}
|
||||
|
||||
/* Register the interrupt handler */
|
||||
if (bus_setup_intr(dev, mpt->pci_irq,
|
||||
INTR_TYPE_CAM, (void (*)(void *))mpt_intr,
|
||||
if (bus_setup_intr(dev, mpt->pci_irq, MPT_IFLAGS, mpt_pci_intr,
|
||||
mpt, &mpt->ih)) {
|
||||
device_printf(dev, "could not setup interrupt\n");
|
||||
goto bad;
|
||||
}
|
||||
|
||||
MPT_LOCK_SETUP(mpt);
|
||||
|
||||
/* Disable interrupts at the part */
|
||||
mpt_disable_ints(mpt);
|
||||
|
||||
@ -301,27 +301,35 @@ mpt_attach(device_t dev)
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/* Initialize character device */
|
||||
/* currently closed */
|
||||
mpt->open = 0;
|
||||
/*
|
||||
* Save the PCI config register values
|
||||
*
|
||||
* Hard resets are known to screw up the BAR for diagnostic
|
||||
* memory accesses (Mem1).
|
||||
*
|
||||
* Using Mem1 is known to make the chip stop responding to
|
||||
* configuration space transfers, so we need to save it now
|
||||
*/
|
||||
|
||||
/* Save the PCI config register values */
|
||||
/* Hard resets are known to screw up the BAR for diagnostic
|
||||
memory accesses (Mem1). */
|
||||
/* Using Mem1 is known to make the chip stop responding to
|
||||
configuration space transfers, so we need to save it now */
|
||||
mpt_read_config_regs(mpt);
|
||||
|
||||
/* Initialize the hardware */
|
||||
if (mpt->disabled == 0) {
|
||||
if (mpt_init(mpt, MPT_DB_INIT_HOST) != 0)
|
||||
MPT_LOCK(mpt);
|
||||
if (mpt_init(mpt, MPT_DB_INIT_HOST) != 0) {
|
||||
MPT_UNLOCK(mpt);
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/* Attach to CAM */
|
||||
/*
|
||||
* Attach to CAM
|
||||
*/
|
||||
MPTLOCK_2_CAMLOCK(mpt);
|
||||
mpt_cam_attach(mpt);
|
||||
CAMLOCK_2_MPTLOCK(mpt);
|
||||
MPT_UNLOCK(mpt);
|
||||
}
|
||||
|
||||
/* Done */
|
||||
return (0);
|
||||
|
||||
bad:
|
||||
@ -334,11 +342,11 @@ mpt_attach(device_t dev)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
/*
|
||||
* Free bus resources
|
||||
*/
|
||||
static void
|
||||
mpt_free_bus_resources(struct mpt_softc *mpt)
|
||||
mpt_free_bus_resources(mpt_softc_t *mpt)
|
||||
{
|
||||
if (mpt->ih) {
|
||||
bus_teardown_intr(mpt->dev, mpt->pci_irq, mpt->ih);
|
||||
@ -355,23 +363,18 @@ mpt_free_bus_resources(struct mpt_softc *mpt)
|
||||
mpt->pci_reg);
|
||||
mpt->pci_reg = 0;
|
||||
}
|
||||
if (mpt->pci_mem) {
|
||||
bus_release_resource(mpt->dev, SYS_RES_MEMORY, mpt->pci_mem_id,
|
||||
mpt->pci_mem);
|
||||
mpt->pci_mem = 0;
|
||||
}
|
||||
|
||||
MPT_LOCK_DESTROY(mpt);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
/*
|
||||
* Disconnect ourselves from the system.
|
||||
*/
|
||||
static int
|
||||
mpt_detach(device_t dev)
|
||||
{
|
||||
struct mpt_softc *mpt;
|
||||
mpt = (struct mpt_softc*) device_get_softc(dev);
|
||||
mpt_softc_t *mpt;
|
||||
mpt = (mpt_softc_t*) device_get_softc(dev);
|
||||
|
||||
device_printf(mpt->dev,"mpt_detach!\n");
|
||||
|
||||
@ -386,14 +389,14 @@ mpt_detach(device_t dev)
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
/*
|
||||
* Disable the hardware
|
||||
*/
|
||||
static int
|
||||
mpt_shutdown(device_t dev)
|
||||
{
|
||||
struct mpt_softc *mpt;
|
||||
mpt = (struct mpt_softc*) device_get_softc(dev);
|
||||
mpt_softc_t *mpt;
|
||||
mpt = (mpt_softc_t*) device_get_softc(dev);
|
||||
|
||||
if (mpt) {
|
||||
mpt_reset(mpt);
|
||||
@ -403,7 +406,7 @@ mpt_shutdown(device_t dev)
|
||||
|
||||
|
||||
struct imush {
|
||||
struct mpt_softc *mpt;
|
||||
mpt_softc_t *mpt;
|
||||
int error;
|
||||
u_int32_t phys;
|
||||
};
|
||||
@ -418,7 +421,7 @@ mpt_map_rquest(void *arg, bus_dma_segment_t *segs, int nseg, int error)
|
||||
|
||||
|
||||
static int
|
||||
mpt_dma_mem_alloc(struct mpt_softc *mpt)
|
||||
mpt_dma_mem_alloc(mpt_softc_t *mpt)
|
||||
{
|
||||
int i, error;
|
||||
u_char *vptr;
|
||||
@ -551,7 +554,7 @@ mpt_dma_mem_alloc(struct mpt_softc *mpt)
|
||||
/* Deallocate memory that was allocated by mpt_dma_mem_alloc
|
||||
*/
|
||||
static void
|
||||
mpt_dma_mem_free(struct mpt_softc *mpt)
|
||||
mpt_dma_mem_free(mpt_softc_t *mpt)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -581,7 +584,7 @@ mpt_dma_mem_free(struct mpt_softc *mpt)
|
||||
|
||||
/* Reads modifiable (via PCI transactions) config registers */
|
||||
static void
|
||||
mpt_read_config_regs(struct mpt_softc *mpt)
|
||||
mpt_read_config_regs(mpt_softc_t *mpt)
|
||||
{
|
||||
mpt->pci_cfg.Command = pci_read_config(mpt->dev, PCIR_COMMAND, 2);
|
||||
mpt->pci_cfg.LatencyTimer_LineSize =
|
||||
@ -598,7 +601,7 @@ mpt_read_config_regs(struct mpt_softc *mpt)
|
||||
|
||||
/* Sets modifiable config registers */
|
||||
void
|
||||
mpt_set_config_regs(struct mpt_softc *mpt)
|
||||
mpt_set_config_regs(mpt_softc_t *mpt)
|
||||
{
|
||||
u_int32_t val;
|
||||
|
||||
@ -636,3 +639,12 @@ mpt_set_config_regs(struct mpt_softc *mpt)
|
||||
pci_write_config(mpt->dev, PCIR_INTLINE, mpt->pci_cfg.IntLine, 1);
|
||||
pci_write_config(mpt->dev, 0x44, mpt->pci_cfg.PMCSR, 4);
|
||||
}
|
||||
|
||||
static void
|
||||
mpt_pci_intr(void *arg)
|
||||
{
|
||||
mpt_softc_t *mpt = arg;
|
||||
MPT_LOCK(mpt);
|
||||
mpt_intr(mpt);
|
||||
MPT_UNLOCK(mpt);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user