patch-2.3.33 linux/drivers/scsi/scsi_merge.c
Next file: linux/drivers/scsi/sg.c
Previous file: linux/drivers/scsi/scsi_lib.c
Back to the patch index
Back to the overall index
- Lines: 114
- Date:
Tue Dec 14 08:49:00 1999
- Orig file:
v2.3.32/linux/drivers/scsi/scsi_merge.c
- Orig date:
Tue Dec 14 01:27:24 1999
diff -u --recursive --new-file v2.3.32/linux/drivers/scsi/scsi_merge.c linux/drivers/scsi/scsi_merge.c
@@ -156,7 +156,7 @@
* the DMA threshold boundary.
*/
if (dma_host &&
- virt_to_phys(bh->b_data - 1) == ISA_DMA_THRESHOLD) {
+ virt_to_phys(bh->b_data) - 1 == ISA_DMA_THRESHOLD) {
ret++;
} else if (CONTIGUOUS_BUFFERS(bh, bh->b_reqnext)) {
/*
@@ -173,6 +173,43 @@
}
/*
+ * Function: recount_segments()
+ *
+ * Purpose: Recount the number of scatter-gather segments for this request.
+ *
+ * Arguments: req - request that needs recounting.
+ *
+ * Returns: Count of the number of SG segments for the request.
+ *
+ * Lock status: Irrelevant.
+ *
+ * Notes: This is only used when we have partially completed requests
+ * and the bit that is leftover is of an indeterminate size.
+ * This can come up if you get a MEDIUM_ERROR, for example,
+ * as we will have "completed" all of the sectors up to and
+ * including the bad sector, and the leftover bit is what
+ * we have to do now. This tends to be a rare occurence, so
+ * we aren't busting our butts to instantiate separate versions
+ * of this function for the 4 different flag values. We
+ * probably should, however.
+ */
+void
+recount_segments(Scsi_Cmnd * SCpnt)
+{
+ struct request *req;
+ struct Scsi_Host *SHpnt;
+ Scsi_Device * SDpnt;
+
+ req = &SCpnt->request;
+ SHpnt = SCpnt->host;
+ SDpnt = SCpnt->device;
+
+ req->nr_segments = __count_segments(req,
+ CLUSTERABLE_DEVICE(SHpnt, SDpnt),
+ SHpnt->unchecked_isa_dma);
+}
+
+/*
* Function: __scsi_merge_fn()
*
* Purpose: Prototype for queue merge function.
@@ -236,7 +273,7 @@
* the DMA threshold boundary.
*/
if (dma_host &&
- virt_to_phys(req->bhtail->b_data - 1) == ISA_DMA_THRESHOLD) {
+ virt_to_phys(req->bhtail->b_data) - 1 == ISA_DMA_THRESHOLD) {
goto new_segment;
}
if (CONTIGUOUS_BUFFERS(req->bhtail, bh)) {
@@ -256,7 +293,7 @@
* the DMA threshold boundary.
*/
if (dma_host &&
- virt_to_phys(bh->b_data - 1) == ISA_DMA_THRESHOLD) {
+ virt_to_phys(bh->b_data) - 1 == ISA_DMA_THRESHOLD) {
goto new_segment;
}
if (CONTIGUOUS_BUFFERS(bh, req->bh)) {
@@ -380,7 +417,7 @@
* the DMA threshold boundary.
*/
if (dma_host &&
- virt_to_phys(req->bhtail->b_data - 1) == ISA_DMA_THRESHOLD) {
+ virt_to_phys(req->bhtail->b_data) - 1 == ISA_DMA_THRESHOLD) {
goto dont_combine;
}
if (CONTIGUOUS_BUFFERS(req->bhtail, next->bh)) {
@@ -573,7 +610,7 @@
bh; bh = bh->b_reqnext) {
if (use_clustering && bhprev != NULL) {
if (dma_host &&
- virt_to_phys(bhprev->b_data - 1) == ISA_DMA_THRESHOLD) {
+ virt_to_phys(bhprev->b_data) - 1 == ISA_DMA_THRESHOLD) {
/* Nothing - fall through */
} else if (CONTIGUOUS_BUFFERS(bhprev, bh)) {
/*
@@ -612,7 +649,23 @@
for (i = 0; i < count; i++) {
SCpnt->request_bufflen += sgpnt[i].length;
if (virt_to_phys(sgpnt[i].address) + sgpnt[i].length - 1 >
- ISA_DMA_THRESHOLD && !sgpnt[count].alt_address) {
+ ISA_DMA_THRESHOLD) {
+ if( scsi_dma_free_sectors <= 10 ) {
+ /*
+ * If the DMA pool is nearly empty, then
+ * let's stop here. Don't make this request
+ * any larger. This is kind of a safety valve
+ * that we use - we could get screwed later on
+ * if we run out completely.
+ */
+ SCpnt->request_bufflen -= sgpnt[i].length;
+ SCpnt->use_sg = i;
+ if (i == 0) {
+ panic("DMA pool exhausted");
+ }
+ break;
+ }
+
sgpnt[i].alt_address = sgpnt[i].address;
sgpnt[i].address =
(char *) scsi_malloc(sgpnt[i].length);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)