Put some limit checking on dma segments so that

we don't, somehow, inadvertantly overrun the total
number of queue entries for a command + continuation
segments.


git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@680 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
Dotan Barak
2009-02-23 23:18:25 +00:00
parent 6880b800ef
commit 8f6b4e5b99
2 changed files with 37 additions and 1 deletions

View File

@@ -2548,4 +2548,19 @@ typedef struct {
#define ISP24XX_ABTS_RSP_SUBCODE 0x31
#define ISP24XX_NO_TASK 0xffffffff
/*
* Miscellaneous
*
* These are the limits of the number of dma segments we
* can deal with based not on the size of the segment counter
* (which is 16 bits), but on the size of the number of
* queue entries field (which is 8 bits). We assume no
* segments in the first queue entry, so we can either
* have 7 dma segments per continuation entry or 5
* (for 64 bit dma).. multiplying out by 254....
*/
#define ISP_NSEG_MAX 1778
#define ISP_NSEG64_MAX 1270
#endif /* _ISPMBOX_H */

View File

@@ -1627,7 +1627,17 @@ isp_pci_dmasetup_tgt(ispsoftc_t *isp, tmd_xact_t *xact, void *fqe)
sg = NULL;
nseg = 0;
}
if (isp->isp_osinfo.is_64bit_dma) {
if (nseg >= ISP_NSEG64_MAX) {
isp_prt(isp, ISP_LOGERR, "number of segments (%d) exceed maximum we can support (%d)", nseg, ISP_NSEG64_MAX);
xact->td_error = -EFAULT;
return (CMD_COMPLETE);
}
} else if (nseg >= ISP_NSEG_MAX) {
isp_prt(isp, ISP_LOGERR, "number of segments (%d) exceed maximum we can support (%d)", nseg, ISP_NSEG_MAX);
xact->td_error = -EFAULT;
return (CMD_COMPLETE);
}
ret = isp_send_tgt_cmd(isp, fqe, sg, nseg, xact->td_xfrlen, ddir, xact->td_cmd->cd_sense, TMD_SENSELEN);
if (ret == CMD_QUEUED) {
int bin;
@@ -1729,6 +1739,17 @@ isp_pci_dmasetup(ispsoftc_t *isp, Scsi_Cmnd *Cmnd, void *fqe)
sg = NULL;
nseg = 0;
}
if (isp->isp_osinfo.is_64bit_dma) {
if (nseg >= ISP_NSEG64_MAX) {
isp_prt(isp, ISP_LOGERR, "number of segments (%d) exceed maximum we can support (%d)", nseg, ISP_NSEG64_MAX);
XS_SETERR(Cmnd, HBA_BOTCH);
return (CMD_COMPLETE);
}
} else if (nseg >= ISP_NSEG_MAX) {
isp_prt(isp, ISP_LOGERR, "number of segments (%d) exceed maximum we can support (%d)", nseg, ISP_NSEG_MAX);
XS_SETERR(Cmnd, HBA_BOTCH);
return (CMD_COMPLETE);
}
ret = isp_send_cmd(isp, fqe, sg, nseg, XS_XFRLEN(Cmnd), ddir);
if (ret == CMD_QUEUED) {
int bin;