PERFORCE change 167628 for review
Alexander Motin
mav at FreeBSD.org
Sat Aug 22 23:22:53 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=167628
Change 167628 by mav at mav_mavbook on 2009/08/22 23:22:05
Fix ATA_CAM wrapper polling locking.
Fix ATA_CAM wrapper 36bit commands support.
Tune ATA(4) DMA memory allocation.
Affected files ...
.. //depot/projects/scottl-camlock/src/sys/dev/ata/ata-all.c#26 edit
.. //depot/projects/scottl-camlock/src/sys/dev/ata/ata-all.h#19 edit
.. //depot/projects/scottl-camlock/src/sys/dev/ata/ata-dma.c#13 edit
.. //depot/projects/scottl-camlock/src/sys/dev/ata/ata-sata.c#7 edit
.. //depot/projects/scottl-camlock/src/sys/dev/ata/chipsets/ata-ahci.c#8 edit
Differences ...
==== //depot/projects/scottl-camlock/src/sys/dev/ata/ata-all.c#26 (text+ko) ====
@@ -80,6 +80,7 @@
static void bswap(int8_t *, int);
static void btrim(int8_t *, int);
static void bpack(int8_t *, int8_t *, int);
+static void ata_interrupt_locked(void *data);
/* global vars */
MALLOC_DEFINE(M_ATA, "ata_generic", "ATA driver generic layer");
@@ -418,10 +419,26 @@
void
ata_interrupt(void *data)
{
+#ifdef ATA_CAM
struct ata_channel *ch = (struct ata_channel *)data;
+
+ mtx_lock(&ch->state_mtx);
+#endif
+ ata_interrupt_locked(data);
+#ifdef ATA_CAM
+ mtx_unlock(&ch->state_mtx);
+#endif
+}
+
+static void
+ata_interrupt_locked(void *data)
+{
+ struct ata_channel *ch = (struct ata_channel *)data;
struct ata_request *request;
+#ifndef ATA_CAM
mtx_lock(&ch->state_mtx);
+#endif
do {
/* ignore interrupt if its not for us */
if (ch->hw.status && !ch->hw.status(ch->dev))
@@ -449,16 +466,17 @@
ch->state = ATA_IDLE;
#ifdef ATA_CAM
ata_cam_end_transaction(ch->dev, request);
-#endif
+#else
mtx_unlock(&ch->state_mtx);
-#ifndef ATA_CAM
ATA_LOCKING(ch->dev, ATA_LF_UNLOCK);
ata_finish(request);
#endif
return;
}
} while (0);
+#ifndef ATA_CAM
mtx_unlock(&ch->state_mtx);
+#endif
}
/*
@@ -1170,7 +1188,6 @@
struct ata_channel *ch = device_get_softc(dev);
struct ata_request *request;
-//device_printf(dev, "%s\n", __func__);
if (!(request = ata_alloc_request())) {
device_printf(dev, "FAILURE - out of memory in start\n");
ccb->ccb_h.status = CAM_REQ_INVALID;
@@ -1191,14 +1208,19 @@
(uint16_t)ccb->ataio.cmd.features;
request->u.ata.count = ((uint16_t)ccb->ataio.cmd.sector_count_exp << 8) |
(uint16_t)ccb->ataio.cmd.sector_count;
- request->u.ata.lba = ((uint64_t)ccb->ataio.cmd.lba_high_exp << 40) |
+ if (ccb->ataio.cmd.flags & CAM_ATAIO_48BIT) {
+ request->flags |= ATA_R_48BIT;
+ request->u.ata.lba =
+ ((uint64_t)ccb->ataio.cmd.lba_high_exp << 40) |
((uint64_t)ccb->ataio.cmd.lba_mid_exp << 32) |
- ((uint64_t)ccb->ataio.cmd.lba_low_exp << 24) |
- ((uint64_t)ccb->ataio.cmd.lba_high << 16) |
- ((uint64_t)ccb->ataio.cmd.lba_mid << 8) |
- (uint64_t)ccb->ataio.cmd.lba_low;
- if (ccb->ataio.cmd.flags & CAM_ATAIO_48BIT)
- request->flags |= ATA_R_48BIT;
+ ((uint64_t)ccb->ataio.cmd.lba_low_exp << 24);
+ } else {
+ request->u.ata.lba =
+ ((uint64_t)(ccb->ataio.cmd.device & 0x0f) << 24);
+ }
+ request->u.ata.lba |= ((uint64_t)ccb->ataio.cmd.lba_high << 16) |
+ ((uint64_t)ccb->ataio.cmd.lba_mid << 8) |
+ (uint64_t)ccb->ataio.cmd.lba_low;
if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE &&
ccb->ataio.cmd.flags & CAM_ATAIO_DMA)
request->flags |= ATA_R_DMA;
@@ -1244,7 +1266,6 @@
// struct ata_channel *ch = device_get_softc(dev);
union ccb *ccb = request->ccb;
-//device_printf(dev, "%s\n", __func__);
ccb->ccb_h.status &= ~CAM_STATUS_MASK;
if (request->flags & ATA_R_TIMEOUT)
ccb->ccb_h.status |= CAM_CMD_TIMEOUT;
@@ -1429,7 +1450,7 @@
{
struct ata_channel *ch = (struct ata_channel *)cam_sim_softc(sim);
- ata_interrupt(ch);
+ ata_interrupt_locked(ch);
}
#endif
==== //depot/projects/scottl-camlock/src/sys/dev/ata/ata-all.h#19 (text+ko) ====
@@ -246,7 +246,7 @@
#define ATA_AHCI_CL_OFFSET 0
#define ATA_AHCI_FB_OFFSET (ATA_AHCI_CL_SIZE * 32)
#define ATA_AHCI_CT_OFFSET (ATA_AHCI_FB_OFFSET + 4096)
-#define ATA_AHCI_CT_SIZE (1024 + 128)
+#define ATA_AHCI_CT_SIZE (2176 + 128)
struct ata_ahci_dma_prd {
u_int64_t dba;
@@ -260,7 +260,7 @@
u_int8_t cfis[64];
u_int8_t acmd[32];
u_int8_t reserved[32];
-#define ATA_AHCI_DMA_ENTRIES 64
+#define ATA_AHCI_DMA_ENTRIES 129
struct ata_ahci_dma_prd prd_tab[ATA_AHCI_DMA_ENTRIES];
} __packed;
@@ -481,7 +481,7 @@
u_int8_t *work; /* workspace */
bus_addr_t work_bus; /* bus address of dmatab */
-#define ATA_DMA_SLOTS 32
+#define ATA_DMA_SLOTS 1
int dma_slots; /* DMA slots allocated */
struct ata_dmaslot slot[ATA_DMA_SLOTS];
u_int32_t alignment; /* DMA SG list alignment */
==== //depot/projects/scottl-camlock/src/sys/dev/ata/ata-dma.c#13 (text+ko) ====
@@ -78,7 +78,7 @@
ch->dma.segsize = 65536;
ch->dma.max_iosize = 128 * DEV_BSIZE;
ch->dma.max_address = BUS_SPACE_MAXADDR_32BIT;
- ch->dma.dma_slots = 6;
+ ch->dma.dma_slots = 1;
if (bus_dma_tag_create(bus_get_dma_tag(dev), ch->dma.alignment, 0,
ch->dma.max_address, BUS_SPACE_MAXADDR,
@@ -284,8 +284,8 @@
return EIO;
}
- /* set our slot, unit for simplicity XXX SOS NCQ will change that */
- request->dma = &ch->dma.slot[request->unit];
+ /* set our slot. XXX SOS NCQ will change that */
+ request->dma = &ch->dma.slot[0];
if (addr)
dspa.dmatab = addr;
==== //depot/projects/scottl-camlock/src/sys/dev/ata/ata-sata.c#7 (text+ko) ====
@@ -337,9 +337,6 @@
pm_chipid, pm_revision, pm_ports);
}
- /* realloc space for needed DMA slots */
- ch->dma.dma_slots = pm_ports;
-
/* reset all ports and register if anything connected */
for (port=0; port < pm_ports; port++) {
u_int32_t signature;
==== //depot/projects/scottl-camlock/src/sys/dev/ata/chipsets/ata-ahci.c#8 (text+ko) ====
@@ -396,7 +396,7 @@
/* get a piece of the workspace for this request */
ctp = (struct ata_ahci_cmd_tab *)
- (ch->dma.work + ATA_AHCI_CT_OFFSET + (ATA_AHCI_CT_SIZE*request->tag));
+ (ch->dma.work + ATA_AHCI_CT_OFFSET);
/* setup the FIS for this request */
if (!(fis_size = ata_ahci_setup_fis(ctp, request))) {
@@ -416,7 +416,7 @@
/* setup the command list entry */
clp = (struct ata_ahci_cmd_list *)
- (ch->dma.work + ATA_AHCI_CL_OFFSET + (ATA_AHCI_CL_SIZE*request->tag));
+ (ch->dma.work + ATA_AHCI_CL_OFFSET);
clp->prd_length = entries;
clp->cmd_flags = (request->flags & ATA_R_WRITE ? ATA_AHCI_CMD_WRITE : 0) |
@@ -425,13 +425,8 @@
(fis_size / sizeof(u_int32_t)) |
(port << 12);
clp->bytecount = 0;
- clp->cmd_table_phys = htole64(ch->dma.work_bus + ATA_AHCI_CT_OFFSET +
- (ATA_AHCI_CT_SIZE * request->tag));
+ clp->cmd_table_phys = htole64(ch->dma.work_bus + ATA_AHCI_CT_OFFSET);
- /* clear eventual ACTIVE bit */
- ATA_IDX_OUTL(ch, ATA_SACTIVE,
- ATA_IDX_INL(ch, ATA_SACTIVE) & (1 << request->tag));
-
/* set command type bit */
if (request->flags & ATA_R_ATAPI)
ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_CMD + offset,
@@ -443,7 +438,7 @@
~ATA_AHCI_P_CMD_ATAPI);
/* issue command to controller */
- ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_CI + offset, (1 << request->tag));
+ ATA_OUTL(ctlr->r_res2, ATA_AHCI_P_CI + offset, 1);
if (!(request->flags & ATA_R_ATAPI)) {
/* device reset doesn't interrupt */
@@ -509,7 +504,7 @@
/* record how much data we actually moved */
clp = (struct ata_ahci_cmd_list *)
- (ch->dma.work + ATA_AHCI_CL_OFFSET + (ATA_AHCI_CL_SIZE*request->tag));
+ (ch->dma.work + ATA_AHCI_CL_OFFSET);
request->donecount = clp->bytecount;
/* release SG list etc */
More information about the p4-projects
mailing list