On Wed, Sep 28, 2011 at 6:47 PM, Dan Williams <dan.j.williams@xxxxxxxxx> wrote: > Based on original implementation from Jiangbi Liu and Maciej Trela. > > ATAPI transfers happen in two-to-three stages. The two stage atapi > commands are those that include a dma data transfer. The data transfer > portion of these operations is handled by the hardware packet-dma > acceleration. The three-stage commands do not have a data transfer and > are handled without hardware assistance in raw frame mode. > > stage1: transmit host-to-device fis to notify the device of an incoming > atapi cdb. Upon reception of the pio-setup-fis repost the task_context > to perform the dma transfer of the cdb+data (go to stage3), or repost > the task_context to transmit the cdb as a raw frame (go to stage 2). > > stage2: wait for hardware notification of the cdb transmission and then > go to stage 3. > > stage3: wait for the arrival of the terminating device-to-host fis and > terminate the command. > > To keep the implementation simple we only support ATAPI packet-dma > protocol (for commands with data) to avoid needing to handle the data > transfer manually (like we do for SATA-PIO). This may affect > compatibility for a small number of devices (see > ATA_HORKAGE_ATAPI_MOD16_DMA). > > If the data-transfer underruns, or encounters an error the > device-to-host fis is expected to arrive in the unsolicited frame queue > to pass to libata for disposition. However, in the DONE_UNEXP_FIS (data > underrun) case it appears we need to craft a response. In the > DONE_REG_ERR case we do receive the UF and propagate it to libsas. > > Signed-off-by: Maciej Trela <maciej.trela@xxxxxxxxx> > Signed-off-by: Dan Williams <dan.j.williams@xxxxxxxxx> > --- > drivers/scsi/isci/remote_device.c | 24 +++ > drivers/scsi/isci/remote_device.h | 9 + > drivers/scsi/isci/request.c | 327 ++++++++++++++++++++++++++++++++++- > drivers/scsi/isci/request.h | 28 +++ > drivers/scsi/libsas/sas_scsi_host.c | 2 > include/scsi/libsas.h | 5 + > 6 files changed, 379 insertions(+), 16 deletions(-) > [..] > diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c > index b5d3a8c..2bf072f 100644 > --- a/drivers/scsi/isci/request.c > +++ b/drivers/scsi/isci/request.c [..] > @@ -2802,26 +3096,29 @@ static void sci_request_started_state_enter(struct sci_base_state_machine *sm) > * substates > */ > if (!task && dev->dev_type == SAS_END_DEV) { > - sci_change_state(sm, SCI_REQ_TASK_WAIT_TC_COMP); > + state = SCI_REQ_TASK_WAIT_TC_COMP; > } else if (!task && > (isci_request_access_tmf(ireq)->tmf_code == isci_tmf_sata_srst_high || > isci_request_access_tmf(ireq)->tmf_code == isci_tmf_sata_srst_low)) { > - sci_change_state(sm, SCI_REQ_STP_SOFT_RESET_WAIT_H2D_ASSERTED); > + state = SCI_REQ_STP_SOFT_RESET_WAIT_H2D_ASSERTED; > } else if (task && task->task_proto == SAS_PROTOCOL_SMP) { > - sci_change_state(sm, SCI_REQ_SMP_WAIT_RESP); > + state = SCI_REQ_SMP_WAIT_RESP; > } else if (task && sas_protocol_ata(task->task_proto) && > !task->ata_task.use_ncq) { > - u32 state; > - > - if (task->data_dir == DMA_NONE) > + if (dev->sata_dev.command_set == ATAPI_COMMAND_SET && > + task->ata_task.fis.command == ATA_CMD_PACKET) { > + state = SCI_REQ_ATAPI_WAIT_H2D; > + } else if (task->data_dir == DMA_NONE) { > state = SCI_REQ_STP_NON_DATA_WAIT_H2D; > - else if (task->ata_task.dma_xfer) > + } else if (task->ata_task.dma_xfer) { > state = SCI_REQ_STP_UDMA_WAIT_TC_COMP; > - else /* PIO */ > + } else /* PIO */ { > state = SCI_REQ_STP_PIO_WAIT_H2D; > - > - sci_change_state(sm, state); > + } > + } else { > + BUG(); Unfortunately this was part of a last minute "cleanup" that missed the fact that SSP and STP-NCQ commands are fully accelerated and do not have a substate. To prevent this mistake in the future I changed this to: @@ -3106,7 +3106,8 @@ static void sci_request_started_state_enter(struct sci_base_state_machine *sm) state = SCI_REQ_STP_PIO_WAIT_H2D; } } else { - BUG(); + /* SSP or NCQ are fully accelerated, no substates */ + return; } sci_change_state(sm, state); } A v2 will be posted shortly and the github branch will be updated. -- Dan -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html