📄 sscsi.c
字号:
if ((dstat & C8XX_INT_SIR) &&
vector == A_err_cmd_complete) {
// SCRIPTS complete, SCSI complete
retval = ERR_SUCCESS;
}
// add other error codes here as needed
else if (sist & C8XX_INT_STO) {
// select timeout
retval = ERR_SELECT;
}
}
else {
// ISTAT poll timed out
retval = ERR_TIMEOUT;
}
return retval;
}
/*--------------------------------------------------*/
/* */
/* Routine to execute Request Sense command. */
/* */
/* Usage: int request_sense( */
/* pci_device *ppcidev, */
/* scsi_device *pscsidev); */
/* */
/* Parameters: */
/* ppcidev: pointer to PCI device */
/* pscsidev: pointer to target SCSI device */
/* */
/* Return value: */
/* Returns error code defined in SSCSI.H */
/* */
/*--------------------------------------------------*/
int request_sense(pci_device *ppcidev,
scsi_device *pscsidev)
{
int retval = ERR_OTHER;
BYTE dstat, istat;
WORD sist;
DWORD vector;
// set the DSA register to the table address
IOWrite32(ppcidev->io_base + DSA,
getPhysAddr(ptable));
// set selection info
ptable[SCSI_ID].count =
(0x0300L | pscsidev->targ_id) << 16;
// set identify message
ptable[MSGOUT_BUF].count = 1L;
msgout_buf[0] = 0x80;
// set data input buffer
ptable[DATAIN_BUF].count = 14L;
ptable[DATAIN_BUF].address =
getPhysAddr(sense_buf);
// set command buffer for Request Sense
memset(cmd_buf, 0, sizeof(cmd_buf));
ptable[CMD_BUF].count = 6L;
cmd_buf[0] = CMD_REQUEST_SENSE;
cmd_buf[4] = (BYTE) ptable[DATAIN_BUF].count;
// start script execution
IOWrite32(ppcidev->io_base + DSP,
getPhysAddr(pscript) + Ent_start_scsi);
// wait for interrupt to complete
if (poll_istat(ppcidev->io_base,
&vector, &dstat, &istat, &sist)) {
// check interrupt type
if ((dstat & C8XX_INT_SIR) &&
vector == A_err_cmd_complete) {
// SCRIPTS complete, SCSI complete
retval = check_status(ppcidev,
pscsidev);
}
// add other error codes here as needed
else if (sist & C8XX_INT_STO) {
// select timeout
retval = ERR_SELECT;
}
}
else {
// ISTAT poll timed out
retval = ERR_TIMEOUT;
}
return retval;
}
/*--------------------------------------------------*/
/* */
/* Routine to execute Inquiry command. */
/* */
/* Usage: int device_inquiry( */
/* pci_device *ppcidev, */
/* scsi_device *pscsidev); */
/* */
/* Parameters: */
/* ppcidev: pointer to PCI device */
/* pscsidev: pointer to target SCSI device */
/* */
/* Return value: */
/* Returns error code defined in SSCSI.H */
/* */
/*--------------------------------------------------*/
int device_inquiry(pci_device *ppcidev,
scsi_device *pscsidev)
{
int retval = ERR_OTHER;
BYTE dstat, istat;
WORD sist;
DWORD vector;
// set the DSA register to the table address
IOWrite32(ppcidev->io_base + DSA,
getPhysAddr(ptable));
// set selection info
ptable[SCSI_ID].count =
(0x0300L | pscsidev->targ_id) << 16;
// set identify message
ptable[MSGOUT_BUF].count = 1L;
msgout_buf[0] = 0x80;
// set data input buffer
ptable[DATAIN_BUF].count = 36L;
ptable[DATAIN_BUF].address =
getPhysAddr(datain_buf);
// set command buffer for Inquiry
memset(cmd_buf, 0, sizeof(cmd_buf));
ptable[CMD_BUF].count = 6L;
cmd_buf[0] = CMD_INQUIRY;
cmd_buf[4] = (BYTE) ptable[DATAIN_BUF].count;
// start script execution
IOWrite32(ppcidev->io_base + DSP,
getPhysAddr(pscript) + Ent_start_scsi);
// wait for interrupt to complete
if (poll_istat(ppcidev->io_base,
&vector, &dstat, &istat, &sist)) {
// check interrupt type
if ((dstat & C8XX_INT_SIR) &&
vector == A_err_cmd_complete) {
// SCRIPTS complete, SCSI complete
retval = check_status(ppcidev,
pscsidev);
}
// add other error codes here as needed
else if (sist & C8XX_INT_STO) {
// select timeout
retval = ERR_SELECT;
}
}
else {
// ISTAT poll timed out
retval = ERR_TIMEOUT;
}
return retval;
}
/*--------------------------------------------------*/
/* */
/* Routine to execute Read Capacity command. */
/* */
/* Usage: int read_capacity( */
/* pci_device *ppcidev, */
/* scsi_device *pscsidev); */
/* */
/* Parameters: */
/* ppcidev: pointer to PCI device */
/* pscsidev: pointer to target SCSI device */
/* */
/* Return value: */
/* Returns error code defined in SSCSI.H */
/* */
/*--------------------------------------------------*/
int read_capacity(pci_device *ppcidev,
scsi_device *pscsidev)
{
int retval = ERR_OTHER;
BYTE dstat, istat;
WORD sist;
DWORD vector;
// set the DSA register to the table address
IOWrite32(ppcidev->io_base + DSA,
getPhysAddr(ptable));
// set selection info
ptable[SCSI_ID].count =
(0x0300L | pscsidev->targ_id) << 16;
// set identify message
ptable[MSGOUT_BUF].count = 1L;
msgout_buf[0] = 0x80;
// set data input buffer
ptable[DATAIN_BUF].count = 8L;
ptable[DATAIN_BUF].address =
getPhysAddr(datain_buf);
// set command buffer for Read Capacity
memset(cmd_buf, 0, sizeof(cmd_buf));
ptable[CMD_BUF].count = 10L;
cmd_buf[0] = CMD_READ_CAPACITY;
// start script execution
IOWrite32(ppcidev->io_base + DSP,
getPhysAddr(pscript) + Ent_start_scsi);
// wait for interrupt to complete
if (poll_istat(ppcidev->io_base,
&vector, &dstat, &istat, &sist)) {
// check interrupt type
if ((dstat & C8XX_INT_SIR) &&
vector == A_err_cmd_complete) {
// SCRIPTS complete, SCSI complete
retval = check_status(ppcidev,
pscsidev);
}
// add other error codes here as needed
else if (sist & C8XX_INT_STO) {
// select timeout
retval = ERR_SELECT;
}
}
else {
// ISTAT poll timed out
retval = ERR_TIMEOUT;
}
return retval;
}
/*--------------------------------------------------*/
/* */
/* Routine to execute Read command for block */
/* oriented device. */
/* */
/* Usage: int read_block( */
/* pci_device *ppcidev, */
/* scsi_device *pscsidev, */
/* DWORD blk_num, BYTE nblocks); */
/* */
/* Parameters: */
/* ppcidev: pointer to PCI device */
/* pscsidev: pointer to target SCSI device */
/* blk_num: starting block number */
/* nblocks: number of blocks to read */
/* */
/* Return value: */
/* Returns error code defined in SSCSI.H */
/* */
/* Note: */
/* This is an experimental routine that uses a */
/* the statically allocated buffer declared */
/* above. Watch the read size. */
/* */
/*--------------------------------------------------*/
int read_block(pci_device *ppcidev,
scsi_device *pscsidev, DWORD blk_num, BYTE nblocks)
{
int retval = ERR_OTHER;
BYTE dstat, istat;
WORD sist;
DWORD vector;
DWORD size;
// set the DSA register to the table address
IOWrite32(ppcidev->io_base + DSA,
getPhysAddr(ptable));
// set selection info
ptable[SCSI_ID].count =
(0x0300L | pscsidev->targ_id) << 16;
// set identify message with disconnect privilege
ptable[MSGOUT_BUF].count = 1L;
msgout_buf[0] = 0xC0;
// set data input buffer
size = nblocks * pscsidev->blk_size;
if (size > sizeof(block_buf)) {
// buffer too small
return ERR_OTHER;
}
ptable[DATAIN_BUF].count = size;
ptable[DATAIN_BUF].address =
getPhysAddr(block_buf);
// set command buffer for Read
memset(cmd_buf, 0, sizeof(cmd_buf));
ptable[CMD_BUF].count = 6L;
cmd_buf[0] = CMD_READ_6;
cmd_buf[1] = (BYTE) (blk_num >> 16) & 0x1F;
cmd_buf[2] = (BYTE) (blk_num >> 8) & 0xFF;
cmd_buf[3] = (BYTE) blk_num & 0xFF;
cmd_buf[4] = nblocks;
// start script execution
IOWrite32(ppcidev->io_base + DSP,
getPhysAddr(pscript) + Ent_start_scsi);
// wait for interrupt to complete
if (poll_istat(ppcidev->io_base,
&vector, &dstat, &istat, &sist)) {
// check interrupt type
if ((dstat & C8XX_INT_SIR) &&
vector == A_err_cmd_complete) {
// SCRIPTS complete, SCSI complete
retval = check_status(ppcidev,
pscsidev);
}
// add other error codes here as needed
else if (sist & C8XX_INT_STO) {
// select timeout
retval = ERR_SELECT;
}
}
else {
// ISTAT poll timed out
retval = ERR_TIMEOUT;
}
return retval;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -