mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] Update powermac IDE driver
@ 2002-11-07  2:42 Paul Mackerras
  2002-11-08 17:39 ` Alan Cox
  0 siblings, 1 reply; 2+ messages in thread
From: Paul Mackerras @ 2002-11-07  2:42 UTC (permalink / raw)
  To: Jens Axboe, torvalds; +Cc: linux-kernel, benh

This patch updates the powermac IDE driver in 2.5 so it uses the 2.5
kernel interfaces and types rather than the 2.4 ones.  It also makes
it use blk_rq_map_sg rather than its own code to set up scatter/gather
lists in pmac_ide_build_sglist, and makes it use ide_lock instead of
io_request_lock.

Jens/Linus, please apply.

Paul.

diff -urN linux-2.5/drivers/ide/ppc/pmac.c pmac-2.5/drivers/ide/ppc/pmac.c
--- linux-2.5/drivers/ide/ppc/pmac.c	2002-10-30 01:37:31.000000000 +1100
+++ pmac-2.5/drivers/ide/ppc/pmac.c	2002-11-02 07:27:28.000000000 +1100
@@ -717,11 +717,11 @@
 		name = pmac_ide[i].node->full_name;
 		if (memcmp(name, bootdevice, n) == 0 && name[n] == 0) {
 			/* XXX should cope with the 2nd drive as well... */
-			return MKDEV(ide_majors[i], 0);
+			return mk_kdev(ide_majors[i], 0);
 		}
 	}
 
-	return 0;
+	return NODEV;
 }
 
 void __init
@@ -932,47 +932,32 @@
 #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
 
 static int
-pmac_ide_build_sglist(ide_hwif_t *hwif, struct request *rq)
+pmac_ide_build_sglist(ide_drive_t *drive, struct request *rq)
 {
+	ide_hwif_t *hwif = HWIF(drive);
 	pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)hwif->hwif_data;
-	struct buffer_head *bh;
 	struct scatterlist *sg = pmif->sg_table;
-	int nents = 0;
+	int nents;
 
 	if (hwif->sg_dma_active)
 		BUG();
 		
-	if (rq->cmd == READ)
+	nents = blk_rq_map_sg(&drive->queue, rq, sg);
+		
+	if (rq_data_dir(rq) == READ)
 		pmif->sg_dma_direction = PCI_DMA_FROMDEVICE;
 	else
 		pmif->sg_dma_direction = PCI_DMA_TODEVICE;
-	bh = rq->bh;
-	do {
-		unsigned char *virt_addr = bh->b_data;
-		unsigned int size = bh->b_size;
-
-		if (nents >= MAX_DCMDS)
-			return 0;
-
-		while ((bh = bh->b_reqnext) != NULL) {
-			if ((virt_addr + size) != (unsigned char *) bh->b_data)
-				break;
-			size += bh->b_size;
-		}
-		memset(&sg[nents], 0, sizeof(*sg));
-		sg[nents].address = virt_addr;
-		sg[nents].length = size;
-		nents++;
-	} while (bh != NULL);
 
 	return pci_map_sg(hwif->pci_dev, sg, nents, pmif->sg_dma_direction);
 }
 
 static int
-pmac_ide_raw_build_sglist(ide_hwif_t *hwif, struct request *rq)
+pmac_ide_raw_build_sglist(ide_drive_t *drive, struct request *rq)
 {
+	ide_hwif_t *hwif = HWIF(drive);
 	pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)hwif->hwif_data;
-	struct scatterlist *sg = hwif->sg_table;
+	struct scatterlist *sg = pmif->sg_table;
 	int nents = 0;
 	ide_task_t *args = rq->special;
 	unsigned char *virt_addr = rq->buffer;
@@ -983,16 +968,18 @@
 	else
 		pmif->sg_dma_direction = PCI_DMA_FROMDEVICE;
 	
-	if (sector_count > 128) {
+	if (sector_count > 127) {
 		memset(&sg[nents], 0, sizeof(*sg));
-		sg[nents].address = virt_addr;
-		sg[nents].length = 128  * SECTOR_SIZE;
+		sg[nents].page = virt_to_page(virt_addr);
+		sg[nents].offset = (unsigned long) virt_addr & ~PAGE_MASK;
+		sg[nents].length = 127  * SECTOR_SIZE;
 		nents++;
-		virt_addr = virt_addr + (128 * SECTOR_SIZE);
-		sector_count -= 128;
+		virt_addr = virt_addr + (127 * SECTOR_SIZE);
+		sector_count -= 127;
 	}
 	memset(&sg[nents], 0, sizeof(*sg));
-	sg[nents].address = virt_addr;
+	sg[nents].page = virt_to_page(virt_addr);
+	sg[nents].offset = (unsigned long) virt_addr & ~PAGE_MASK;
 	sg[nents].length =  sector_count  * SECTOR_SIZE;
 	nents++;
    
@@ -1023,10 +1010,10 @@
 		udelay(1);
 
 	/* Build sglist */
-	if (rq->cmd == IDE_DRIVE_TASKFILE)
-		pmif->sg_nents = i = pmac_ide_raw_build_sglist(hwif, rq);
+	if (HWGROUP(drive)->rq->flags & REQ_DRIVE_TASKFILE)
+		pmif->sg_nents = i = pmac_ide_raw_build_sglist(drive, rq);
 	else
-		pmif->sg_nents = i = pmac_ide_build_sglist(hwif, rq);
+		pmif->sg_nents = i = pmac_ide_build_sglist(drive, rq);
 	if (!i)
 		return 0;
 
@@ -1045,7 +1032,7 @@
 			if (++count >= MAX_DCMDS) {
 				printk(KERN_WARNING "%s: DMA table too small\n",
 				       drive->name);
-				return 0; /* revert to PIO for this request */
+				goto use_pio_instead;
 			}
 			st_le16(&table->command, wr? OUTPUT_MORE: INPUT_MORE);
 			st_le16(&table->req_count, tc);
@@ -1062,17 +1049,24 @@
 	}
 
 	/* convert the last command to an input/output last command */
-	if (count)
+	if (count) {
 		st_le16(&table[-1].command, wr? OUTPUT_LAST: INPUT_LAST);
-	else
-		printk(KERN_DEBUG "%s: empty DMA table?\n", drive->name);
+		/* add the stop command to the end of the list */
+		memset(table, 0, sizeof(struct dbdma_cmd));
+		st_le16(&table->command, DBDMA_STOP);
+		mb();
+		writel(pmif->dma_table_dma, &dma->cmdptr);
+		return 1;
+	}
 
-	/* add the stop command to the end of the list */
-	memset(table, 0, sizeof(struct dbdma_cmd));
-	st_le16(&table->command, DBDMA_STOP);
-	mb();
-	writel(pmif->dma_table_dma, &dma->cmdptr);
-	return 1;
+	printk(KERN_DEBUG "%s: empty DMA table?\n", drive->name);
+ use_pio_instead:
+	pci_unmap_sg(hwif->pci_dev,
+		     pmif->sg_table,
+		     pmif->sg_nents,
+		     pmif->sg_dma_direction);
+	hwif->sg_dma_active = 0;
+	return 0; /* revert to PIO for this request */
 }
 
 /* Teardown mappings after DMA has completed.  */
@@ -1279,7 +1273,7 @@
 	}
 #else
 	command = (lba48) ? WIN_READDMA_EXT : WIN_READDMA;
-	if (rq->cmd == IDE_DRIVE_TASKFILE) {
+	if (rq->flags & REQ_DRIVE_TASKFILE) {
 		ide_task_t *args = rq->special;
 		command = args->tfRegister[IDE_COMMAND_OFFSET];
 	}
@@ -1332,7 +1326,7 @@
 	}
 #else
 	command = (lba48) ? WIN_WRITEDMA_EXT : WIN_WRITEDMA;
-	if (rq->cmd == IDE_DRIVE_TASKFILE) {
+	if (rq->flags & REQ_DRIVE_TASKFILE) {
 		ide_task_t *args = rq->special;
 		command = args->tfRegister[IDE_COMMAND_OFFSET];
 	}
@@ -1579,8 +1573,8 @@
 	 * Problem: This can schedule. I moved the block device
 	 * wakeup almost late by priority because of that.
 	 */
-	if (DRIVER(drive))
-		check_disk_change(MKDEV(drive->disk->major, drive->disk->first_minor));
+	//if (DRIVER(drive))
+	//	check_disk_change(MKDEV(drive->disk->major, drive->disk->first_minor));
 	
 #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
 	/* We re-enable DMA on the drive if it was active. */
@@ -1595,7 +1589,7 @@
 		HWGROUP(drive)->busy = 0;
 		if (!list_empty(&drive->queue.queue_head))
 			ide_do_request(HWGROUP(drive), 0);
-		spin_unlock_irq(&io_request_lock);
+		spin_unlock_irq(&ide_lock);
 	}
 #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */
 }
@@ -1648,7 +1642,7 @@
 		idepmac_sleep_device(drive, base);
 	}
 	if (unlock)
-		spin_unlock_irq(&io_request_lock);
+		spin_unlock_irq(&ide_lock);
 }
 
 static void
@@ -1675,11 +1669,11 @@
 	}
 
 	/* We resume processing on the HW group */
-	spin_lock_irqsave(&io_request_lock, flags);
+	spin_lock_irqsave(&ide_lock, flags);
 	HWGROUP(drive)->busy = 0;
 	if (!list_empty(&drive->queue.queue_head))
 		ide_do_request(HWGROUP(drive), 0);
-	spin_unlock_irqrestore(&io_request_lock, flags);			
+	spin_unlock_irqrestore(&ide_lock, flags);
 }
 
 /* Note: We support only master drives for now. This will have to be

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2002-11-08 17:09 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-11-07  2:42 [PATCH] Update powermac IDE driver Paul Mackerras
2002-11-08 17:39 ` Alan Cox

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®