New struct ata_request.
Added ata_request as wrapper around scsi_ccb while they are executed in the ata stack. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23344 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
0625889c61
commit
a3af33c75d
@ -6,6 +6,7 @@ UsePrivateHeaders [ FDirName kernel boot platform $(TARGET_BOOT_PLATFORM) ] ;
|
||||
|
||||
KernelAddon ide :
|
||||
ata.c
|
||||
ata_request.c
|
||||
atapi.c
|
||||
channels.c
|
||||
devices.c
|
||||
|
153
src/add-ons/kernel/bus_managers/ata/ata_request.c
Normal file
153
src/add-ons/kernel/bus_managers/ata/ata_request.c
Normal file
@ -0,0 +1,153 @@
|
||||
|
||||
#include "ata_request.h"
|
||||
#include "ide_internal.h"
|
||||
#include "scsi_cmds.h"
|
||||
#include <string.h>
|
||||
|
||||
#define TRACE dprintf
|
||||
|
||||
void
|
||||
ata_request_init(ata_request *request, struct ide_device_info *device)
|
||||
{
|
||||
memset(request, 0, sizeof(request));
|
||||
request->device = device;
|
||||
}
|
||||
|
||||
|
||||
/* Start the request, but don't clear sense to allow
|
||||
* retrieving the previous sense data.
|
||||
*/
|
||||
void ata_request_start(ata_request **_request, struct ide_device_info *device, struct scsi_ccb *ccb)
|
||||
{
|
||||
ata_request *request;
|
||||
|
||||
IDE_LOCK(device->bus);
|
||||
if (device->bus->state != ata_state_idle) {
|
||||
request = NULL;
|
||||
} else {
|
||||
ASSERT(device->requestFree != NULL);
|
||||
ASSERT(device->requestActive == NULL);
|
||||
ASSERT(device->bus->active_device == NULL);
|
||||
|
||||
device->bus->state = ata_state_busy;
|
||||
device->bus->active_device = device;
|
||||
|
||||
request = device->requestFree;
|
||||
device->requestActive = request;
|
||||
device->requestFree = NULL;
|
||||
}
|
||||
IDE_UNLOCK(device->bus);
|
||||
|
||||
*_request = request;
|
||||
|
||||
if (!request)
|
||||
return; // bus was busy
|
||||
|
||||
ASSERT(request->device == device);
|
||||
|
||||
request->ccb = ccb;
|
||||
request->is_write = 0;
|
||||
request->uses_dma = 0;
|
||||
request->packet_irq = 0;
|
||||
|
||||
ASSERT(request->ccb->subsys_status == SCSI_REQ_INPROG);
|
||||
|
||||
// pretend success
|
||||
request->ccb->subsys_status = SCSI_REQ_CMP;
|
||||
|
||||
// device_status always remains set to SCSI_STATUS_GOOD
|
||||
// except when ata_request_set_checkcondition() is called.
|
||||
request->ccb->device_status = SCSI_STATUS_GOOD;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ata_request_clear_sense(ata_request *request)
|
||||
{
|
||||
request->senseKey = 0;
|
||||
request->senseAsc = 0;
|
||||
request->senseAscq = 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ata_request_set_status(ata_request *request, uint8 status)
|
||||
{
|
||||
ASSERT(status != SCSI_REQ_CMP);
|
||||
request->ccb->subsys_status = status;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ata_request_set_sense(ata_request *request, uint8 key, uint16 asc_acq)
|
||||
{
|
||||
request->senseKey = key;
|
||||
request->senseAsc = asc_acq >> 8;
|
||||
request->senseAscq = asc_acq & 0xff;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ata_request_finish(ata_request *request, bool resubmit)
|
||||
{
|
||||
scsi_ccb *ccb;
|
||||
|
||||
TRACE("ata_request_finish: request %p, subsys_status 0x%02x, senseKey %02x\n",
|
||||
request, request->ccb->subsys_status, request->senseKey);
|
||||
|
||||
// when the request completed and has set sense
|
||||
// data, report this to the scsci stack by setting
|
||||
// CHECK CONDITION status
|
||||
if (request->ccb->subsys_status == SCSI_REQ_CMP && request->senseKey != 0) {
|
||||
|
||||
TRACE("ata_request_finish - setting check condition\n");
|
||||
|
||||
request->ccb->subsys_status = SCSI_REQ_CMP_ERR;
|
||||
request->ccb->device_status = SCSI_STATUS_CHECK_CONDITION;
|
||||
|
||||
// copy sense data if caller requested it
|
||||
if ((request->ccb->flags & SCSI_DIS_AUTOSENSE) == 0) {
|
||||
scsi_sense sense;
|
||||
int sense_len;
|
||||
|
||||
TRACE("ata_request_finish - copying autosense data\n");
|
||||
|
||||
// we cannot copy sense directly as sense buffer may be too small
|
||||
scsi_set_sense(&sense, request);
|
||||
|
||||
ASSERT(sizeof(*request->ccb->sense) == SCSI_MAX_SENSE_SIZE);
|
||||
|
||||
sense_len = min(sizeof(*request->ccb->sense), sizeof(sense));
|
||||
|
||||
memcpy(request->ccb->sense, &sense, sense_len);
|
||||
request->ccb->sense_resid = SCSI_MAX_SENSE_SIZE - sense_len;
|
||||
request->ccb->subsys_status |= SCSI_AUTOSNS_VALID;
|
||||
|
||||
// device sense gets reset once it's read
|
||||
ata_request_clear_sense(request);
|
||||
|
||||
ASSERT(request->ccb->subsys_status == SCSI_REQ_CMP_ERR);
|
||||
ASSERT(request->ccb->device_status == SCSI_STATUS_CHECK_CONDITION);
|
||||
}
|
||||
}
|
||||
|
||||
ccb = request->ccb;
|
||||
|
||||
IDE_LOCK(request->device->bus);
|
||||
ASSERT(request->device->bus->state == ata_state_busy);
|
||||
ASSERT(request->device->bus->active_device == request->device);
|
||||
ASSERT(request->device->requestActive == request);
|
||||
ASSERT(request->device->requestFree == NULL);
|
||||
request->device->bus->state = ata_state_idle;
|
||||
request->device->bus->active_device = NULL;
|
||||
request->device->requestActive = NULL;
|
||||
request->device->requestFree = request;
|
||||
IDE_UNLOCK(request->device->bus);
|
||||
|
||||
ACQUIRE_BEN(&request->device->bus->status_report_ben);
|
||||
if (resubmit)
|
||||
scsi->resubmit(ccb);
|
||||
else
|
||||
scsi->finished(ccb, 1);
|
||||
RELEASE_BEN(&request->device->bus->status_report_ben);
|
||||
}
|
33
src/add-ons/kernel/bus_managers/ata/ata_request.h
Normal file
33
src/add-ons/kernel/bus_managers/ata/ata_request.h
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2008 Marcus Overhagen. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _ATA_REQUEST_H
|
||||
#define _ATA_REQUEST_H
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
typedef struct ata_request {
|
||||
|
||||
struct ide_device_info * device;
|
||||
struct scsi_ccb * ccb; // basic scsi request
|
||||
uint8 is_write : 1; // true for write request
|
||||
uint8 uses_dma : 1; // true if using dma
|
||||
uint8 packet_irq : 1; // true if waiting for command packet irq
|
||||
|
||||
uint8 senseKey;
|
||||
uint8 senseAsc;
|
||||
uint8 senseAscq;
|
||||
} ata_request;
|
||||
|
||||
struct scsi_ccb;
|
||||
struct ide_device_info;
|
||||
|
||||
void ata_request_init(ata_request *request, struct ide_device_info *device);
|
||||
void ata_request_start(ata_request **_request, struct ide_device_info *device, struct scsi_ccb *ccb);
|
||||
void ata_request_clear_sense(ata_request *request);
|
||||
void ata_request_set_status(ata_request *request, uint8 status);
|
||||
void ata_request_set_sense(ata_request *request, uint8 key, uint16 asc_acq);
|
||||
void ata_request_finish(ata_request *request, bool resubmit);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user