Commit 0f82e7a6 authored by Mikhail Karpenko's avatar Mikhail Karpenko

Add WRITE_TEST command, fix error during recording stop

parent c132ac02
...@@ -267,7 +267,7 @@ void process_queue(unsigned long data) ...@@ -267,7 +267,7 @@ void process_queue(unsigned long data)
struct elphel_ahci_priv *dpriv = (struct elphel_ahci_priv *)data; struct elphel_ahci_priv *dpriv = (struct elphel_ahci_priv *)data;
// calculate the speed this frame has been written with // calculate the speed this frame has been written with
get_fpga_rtc(&end_time); // get_fpga_rtc(&end_time);
time_usec = time_diff_usec(&dpriv->stat.start_time, &end_time); time_usec = time_diff_usec(&dpriv->stat.start_time, &end_time);
if (time_usec != 0) { if (time_usec != 0) {
for (i = 0; i < dpriv->sg_elems; i++) for (i = 0; i < dpriv->sg_elems; i++)
...@@ -516,6 +516,10 @@ static void elphel_qc_prep(struct ata_queued_cmd *qc) ...@@ -516,6 +516,10 @@ static void elphel_qc_prep(struct ata_queued_cmd *qc)
opts |= AHCI_CMD_ATAPI | AHCI_CMD_PREFETCH; opts |= AHCI_CMD_ATAPI | AHCI_CMD_PREFETCH;
ahci_fill_cmd_slot(pp, qc->tag, opts); ahci_fill_cmd_slot(pp, qc->tag, opts);
dev_dbg(ap->dev, "dump command table content, first %d bytes, phys addr = 0x%x:\n", 16, pp->cmd_tbl_dma);
print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, pp->cmd_tbl, 16);
dma_sync_single_for_device(&qc->dev->tdev, pp->cmd_tbl_dma, dma_sync_single_for_device(&qc->dev->tdev, pp->cmd_tbl_dma,
AHCI_CMD_TBL_AR_SZ, DMA_TO_DEVICE); AHCI_CMD_TBL_AR_SZ, DMA_TO_DEVICE);
} }
...@@ -1050,9 +1054,10 @@ static int process_cmd(struct elphel_ahci_priv *dpriv) ...@@ -1050,9 +1054,10 @@ static int process_cmd(struct elphel_ahci_priv *dpriv)
} }
dpriv->sg_elems = map_vectors(dpriv); dpriv->sg_elems = map_vectors(dpriv);
if (dpriv->sg_elems != 0) { if (dpriv->sg_elems != 0) {
dump_sg_list(dpriv->dev, dpriv->sgl, dpriv->sg_elems); dump_sg_list(dpriv->dev, dpriv->sgl, dpriv->sg_elems);
get_fpga_rtc(&dpriv->stat.start_time); // get_fpga_rtc(&dpriv->stat.start_time);
set_timer(dpriv); set_timer(dpriv);
dpriv->lba_ptr.wr_count = get_blocks_num(dpriv->sgl, dpriv->sg_elems); dpriv->lba_ptr.wr_count = get_blocks_num(dpriv->sgl, dpriv->sg_elems);
...@@ -1096,8 +1101,11 @@ static void finish_rec(struct elphel_ahci_priv *dpriv) ...@@ -1096,8 +1101,11 @@ static void finish_rec(struct elphel_ahci_priv *dpriv)
struct fvec *cvect = &dpriv->data_chunks[dpriv->head_ptr][CHUNK_COMMON]; struct fvec *cvect = &dpriv->data_chunks[dpriv->head_ptr][CHUNK_COMMON];
struct fvec *rvect = &dpriv->data_chunks[dpriv->head_ptr][CHUNK_REM]; struct fvec *rvect = &dpriv->data_chunks[dpriv->head_ptr][CHUNK_REM];
if (rvect->iov_len == 0) if (rvect->iov_len == 0) {
finish_cmd(dpriv);
reset_flag(dpriv, DISK_BUSY);
return; return;
}
dev_dbg(dpriv->dev, "write last chunk of data from slot %u, size: %u\n", dpriv->head_ptr, rvect->iov_len); dev_dbg(dpriv->dev, "write last chunk of data from slot %u, size: %u\n", dpriv->head_ptr, rvect->iov_len);
stuff_len = PHY_BLOCK_SIZE - rvect->iov_len; stuff_len = PHY_BLOCK_SIZE - rvect->iov_len;
...@@ -1109,7 +1117,10 @@ static void finish_rec(struct elphel_ahci_priv *dpriv) ...@@ -1109,7 +1117,10 @@ static void finish_rec(struct elphel_ahci_priv *dpriv)
vectshrink(rvect, rvect->iov_len); vectshrink(rvect, rvect->iov_len);
dpriv->flags |= LAST_BLOCK; dpriv->flags |= LAST_BLOCK;
process_cmd(dpriv); if (process_cmd(dpriv) == 0) {
finish_cmd(dpriv);
reset_flag(dpriv, DISK_BUSY);
}
} }
/** Move a pointer to free command slot one step forward. This function holds spin lock #elphel_ahci_priv::flags_lock */ /** Move a pointer to free command slot one step forward. This function holds spin lock #elphel_ahci_priv::flags_lock */
...@@ -1218,6 +1229,12 @@ void error_handler(struct elphel_ahci_priv *dpriv) ...@@ -1218,6 +1229,12 @@ void error_handler(struct elphel_ahci_priv *dpriv)
// printk(KERN_DEBUG "OK, going back to commands execution\n"); // printk(KERN_DEBUG "OK, going back to commands execution\n");
} }
static void invalidate_cache(struct fvec *vect)
{
__cpuc_flush_dcache_area(vect->iov_base, vect->iov_len);
outer_inv_range(vect->iov_dma, vect->iov_dma + (vect->iov_len - 1));
}
/** Get and enqueue new command */ /** Get and enqueue new command */
static ssize_t rawdev_write(struct device *dev, ///< device structure associated with the driver static ssize_t rawdev_write(struct device *dev, ///< device structure associated with the driver
struct device_attribute *attr, ///< interface for device attributes struct device_attribute *attr, ///< interface for device attributes
...@@ -1288,6 +1305,7 @@ static ssize_t rawdev_write(struct device *dev, ///< device structure associate ...@@ -1288,6 +1305,7 @@ static ssize_t rawdev_write(struct device *dev, ///< device structure associate
chunks[CHUNK_EXIF].iov_len = rcvd; chunks[CHUNK_EXIF].iov_len = rcvd;
} }
if (!(fdata.cmd & DRV_CMD_WRITE_TEST)) {
rcvd = jpeghead_get_data(fdata.sensor_port, buffs->jpheader_buff.iov_base, buffs->jpheader_buff.iov_len, 0); rcvd = jpeghead_get_data(fdata.sensor_port, buffs->jpheader_buff.iov_base, buffs->jpheader_buff.iov_len, 0);
if (rcvd < 0) { if (rcvd < 0) {
/* free resource lock and current command slot */ /* free resource lock and current command slot */
...@@ -1305,6 +1323,7 @@ static ssize_t rawdev_write(struct device *dev, ///< device structure associate ...@@ -1305,6 +1323,7 @@ static ssize_t rawdev_write(struct device *dev, ///< device structure associate
chunks[CHUNK_LEADER].iov_len = JPEG_MARKER_LEN; chunks[CHUNK_LEADER].iov_len = JPEG_MARKER_LEN;
chunks[CHUNK_TRAILER].iov_len = JPEG_MARKER_LEN; chunks[CHUNK_TRAILER].iov_len = JPEG_MARKER_LEN;
chunks[CHUNK_HEADER].iov_len = rcvd - chunks[CHUNK_LEADER].iov_len; chunks[CHUNK_HEADER].iov_len = rcvd - chunks[CHUNK_LEADER].iov_len;
}
rcvd = circbuf_get_ptr(fdata.sensor_port, fdata.cirbuf_ptr, fdata.jpeg_len, &chunks[CHUNK_DATA_0], &chunks[CHUNK_DATA_1]); rcvd = circbuf_get_ptr(fdata.sensor_port, fdata.cirbuf_ptr, fdata.jpeg_len, &chunks[CHUNK_DATA_0], &chunks[CHUNK_DATA_1]);
if (rcvd < 0) { if (rcvd < 0) {
...@@ -1320,6 +1339,9 @@ static ssize_t rawdev_write(struct device *dev, ///< device structure associate ...@@ -1320,6 +1339,9 @@ static ssize_t rawdev_write(struct device *dev, ///< device structure associate
dev_err(dev, "could not get JPEG data, error %d\n", rcvd); dev_err(dev, "could not get JPEG data, error %d\n", rcvd);
return -EINVAL; return -EINVAL;
} }
if (fdata.cmd & DRV_CMD_WRITE_TEST)
invalidate_cache(&chunks[CHUNK_DATA_0]);
align_frame(dpriv); align_frame(dpriv);
/* new command slot is ready now and can be unlocked */ /* new command slot is ready now and can be unlocked */
reset_flag(dpriv, LOCK_TAIL); reset_flag(dpriv, LOCK_TAIL);
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#define DRV_CMD_WRITE (1 << 0) #define DRV_CMD_WRITE (1 << 0)
#define DRV_CMD_FINISH (1 << 1) #define DRV_CMD_FINISH (1 << 1)
#define DRV_CMD_EXIF (1 << 2) #define DRV_CMD_EXIF (1 << 2)
#define DRV_CMD_WRITE_TEST (1 << 3)
#define _NAME_TO_STR(...) #__VA_ARGS__ #define _NAME_TO_STR(...) #__VA_ARGS__
#define NAME_TO_STR(NAME) _NAME_TO_STR(NAME) #define NAME_TO_STR(NAME) _NAME_TO_STR(NAME)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment