MFp4:
- Add support for sector size > 512 bytes and physical sector of several logical sectors, introduced by ATA-7 specification. - Remove some obsoleted code.
This commit is contained in:
parent
c82b245af9
commit
c1bd46c2d3
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=198897
@ -1061,6 +1061,10 @@ atacapprint(struct ata_params *parm)
|
||||
printf("cylinders %d\n", parm->cylinders);
|
||||
printf("heads %d\n", parm->heads);
|
||||
printf("sectors/track %d\n", parm->sectors);
|
||||
printf("sector size logical %u, physical %lu, offset %lu\n",
|
||||
ata_logical_sector_size(parm),
|
||||
(unsigned long)ata_physical_sector_size(parm),
|
||||
(unsigned long)ata_logical_sector_offset(parm));
|
||||
|
||||
if (parm->config == ATA_PROTO_CFA ||
|
||||
(parm->support.command2 & ATA_SUPPORT_CFA))
|
||||
|
@ -271,6 +271,38 @@ ata_print_ident(struct ata_params *ident_data)
|
||||
printf(" device\n");
|
||||
}
|
||||
|
||||
uint32_t
|
||||
ata_logical_sector_size(struct ata_params *ident_data)
|
||||
{
|
||||
if ((ident_data->pss & 0xc000) == 0x4000 &&
|
||||
(ident_data->pss & ATA_PSS_LSSABOVE512)) {
|
||||
return ((u_int32_t)ident_data->lss_1 |
|
||||
((u_int32_t)ident_data->lss_2 << 16));
|
||||
}
|
||||
return (512);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
ata_physical_sector_size(struct ata_params *ident_data)
|
||||
{
|
||||
if ((ident_data->pss & 0xc000) == 0x4000 &&
|
||||
(ident_data->pss & ATA_PSS_MULTLS)) {
|
||||
return ((uint64_t)ata_logical_sector_size(ident_data) *
|
||||
(1 << (ident_data->pss & ATA_PSS_LSPPS)));
|
||||
}
|
||||
return (512);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
ata_logical_sector_offset(struct ata_params *ident_data)
|
||||
{
|
||||
if ((ident_data->lsalign & 0xc000) == 0x4000) {
|
||||
return ((uint64_t)ata_logical_sector_size(ident_data) *
|
||||
(ident_data->lsalign & 0x3fff));
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
ata_28bit_cmd(struct ccb_ataio *ataio, uint8_t cmd, uint8_t features,
|
||||
uint32_t lba, uint8_t sector_count)
|
||||
|
@ -91,6 +91,10 @@ int ata_res_sbuf(struct ccb_ataio *ataio, struct sbuf *sb);
|
||||
|
||||
void ata_print_ident(struct ata_params *ident_data);
|
||||
|
||||
uint32_t ata_logical_sector_size(struct ata_params *ident_data);
|
||||
uint64_t ata_physical_sector_size(struct ata_params *ident_data);
|
||||
uint64_t ata_logical_sector_offset(struct ata_params *ident_data);
|
||||
|
||||
void ata_28bit_cmd(struct ccb_ataio *ataio, uint8_t cmd, uint8_t features,
|
||||
uint32_t lba, uint8_t sector_count);
|
||||
void ata_48bit_cmd(struct ccb_ataio *ataio, uint8_t cmd, uint16_t features,
|
||||
|
@ -95,16 +95,14 @@ typedef enum {
|
||||
|
||||
struct disk_params {
|
||||
u_int8_t heads;
|
||||
u_int32_t cylinders;
|
||||
u_int8_t secs_per_track;
|
||||
u_int32_t secsize; /* Number of bytes/sector */
|
||||
u_int64_t sectors; /* total number sectors */
|
||||
u_int32_t cylinders;
|
||||
u_int32_t secsize; /* Number of bytes/logical sector */
|
||||
u_int64_t sectors; /* Total number sectors */
|
||||
};
|
||||
|
||||
struct ada_softc {
|
||||
struct bio_queue_head bio_queue;
|
||||
SLIST_ENTRY(ada_softc) links;
|
||||
LIST_HEAD(, ccb_hdr) pending_ccbs;
|
||||
ada_state state;
|
||||
ada_flags flags;
|
||||
ada_quirks quirks;
|
||||
@ -142,7 +140,7 @@ static void adadone(struct cam_periph *periph,
|
||||
union ccb *done_ccb);
|
||||
static int adaerror(union ccb *ccb, u_int32_t cam_flags,
|
||||
u_int32_t sense_flags);
|
||||
static void adasetgeom(struct cam_periph *periph,
|
||||
static void adagetparams(struct cam_periph *periph,
|
||||
struct ccb_getdev *cgd);
|
||||
static timeout_t adasendorderedtag;
|
||||
static void adashutdown(void *arg, int howto);
|
||||
@ -613,7 +611,6 @@ adaregister(struct cam_periph *periph, void *arg)
|
||||
return(CAM_REQ_CMP_ERR);
|
||||
}
|
||||
|
||||
LIST_INIT(&softc->pending_ccbs);
|
||||
bioq_init(&softc->bio_queue);
|
||||
|
||||
if (cgd->ident_data.capabilities1 & ATA_SUPPORT_DMA)
|
||||
@ -658,6 +655,7 @@ adaregister(struct cam_periph *periph, void *arg)
|
||||
* Register this media as a disk
|
||||
*/
|
||||
mtx_unlock(periph->sim->mtx);
|
||||
adagetparams(periph, cgd);
|
||||
softc->disk = disk_alloc();
|
||||
softc->disk->d_open = adaopen;
|
||||
softc->disk->d_close = adaclose;
|
||||
@ -671,9 +669,9 @@ adaregister(struct cam_periph *periph, void *arg)
|
||||
else if (maxio > MAXPHYS)
|
||||
maxio = MAXPHYS; /* for safety */
|
||||
if (cgd->ident_data.support.command2 & ATA_SUPPORT_ADDRESS48)
|
||||
maxio = min(maxio, 65536 * 512);
|
||||
maxio = min(maxio, 65536 * softc->params.secsize);
|
||||
else /* 28bit ATA command limit */
|
||||
maxio = min(maxio, 256 * 512);
|
||||
maxio = min(maxio, 256 * softc->params.secsize);
|
||||
softc->disk->d_maxsize = maxio;
|
||||
softc->disk->d_unit = periph->unit_number;
|
||||
softc->disk->d_flags = 0;
|
||||
@ -682,9 +680,12 @@ adaregister(struct cam_periph *periph, void *arg)
|
||||
strlcpy(softc->disk->d_ident, cgd->serial_num,
|
||||
MIN(sizeof(softc->disk->d_ident), cgd->serial_num_len + 1));
|
||||
|
||||
adasetgeom(periph, cgd);
|
||||
softc->disk->d_sectorsize = softc->params.secsize;
|
||||
softc->disk->d_mediasize = softc->params.secsize * (off_t)softc->params.sectors;
|
||||
softc->disk->d_mediasize = (off_t)softc->params.sectors *
|
||||
softc->params.secsize;
|
||||
softc->disk->d_stripesize = ata_physical_sector_size(&cgd->ident_data);
|
||||
softc->disk->d_stripeoffset = softc->disk->d_stripesize -
|
||||
ata_logical_sector_offset(&cgd->ident_data);
|
||||
/* XXX: these are not actually "firmware" values, so they may be wrong */
|
||||
softc->disk->d_fwsectors = softc->params.secs_per_track;
|
||||
softc->disk->d_fwheads = softc->params.heads;
|
||||
@ -852,19 +853,10 @@ adastart(struct cam_periph *periph, union ccb *start_ccb)
|
||||
break;
|
||||
}
|
||||
start_ccb->ccb_h.ccb_state = ADA_CCB_BUFFER_IO;
|
||||
|
||||
/*
|
||||
* Block out any asyncronous callbacks
|
||||
* while we touch the pending ccb list.
|
||||
*/
|
||||
LIST_INSERT_HEAD(&softc->pending_ccbs,
|
||||
&start_ccb->ccb_h, periph_links.le);
|
||||
softc->outstanding_cmds++;
|
||||
|
||||
start_ccb->ccb_h.ccb_bp = bp;
|
||||
bp = bioq_first(&softc->bio_queue);
|
||||
|
||||
softc->outstanding_cmds++;
|
||||
xpt_action(start_ccb);
|
||||
bp = bioq_first(&softc->bio_queue);
|
||||
}
|
||||
|
||||
if (bp != NULL) {
|
||||
@ -941,12 +933,6 @@ adadone(struct cam_periph *periph, union ccb *done_ccb)
|
||||
if (ataio->resid > 0)
|
||||
bp->bio_flags |= BIO_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Block out any asyncronous callbacks
|
||||
* while we touch the pending ccb list.
|
||||
*/
|
||||
LIST_REMOVE(&done_ccb->ccb_h, periph_links.le);
|
||||
softc->outstanding_cmds--;
|
||||
if (softc->outstanding_cmds == 0)
|
||||
softc->flags |= ADA_FLAG_WENT_IDLE;
|
||||
@ -983,14 +969,14 @@ adaerror(union ccb *ccb, u_int32_t cam_flags, u_int32_t sense_flags)
|
||||
}
|
||||
|
||||
static void
|
||||
adasetgeom(struct cam_periph *periph, struct ccb_getdev *cgd)
|
||||
adagetparams(struct cam_periph *periph, struct ccb_getdev *cgd)
|
||||
{
|
||||
struct ada_softc *softc = (struct ada_softc *)periph->softc;
|
||||
struct disk_params *dp = &softc->params;
|
||||
u_int64_t lbasize48;
|
||||
u_int32_t lbasize;
|
||||
|
||||
dp->secsize = 512;
|
||||
dp->secsize = ata_logical_sector_size(&cgd->ident_data);
|
||||
if ((cgd->ident_data.atavalid & ATA_FLAG_54_58) &&
|
||||
cgd->ident_data.current_heads && cgd->ident_data.current_sectors) {
|
||||
dp->heads = cgd->ident_data.current_heads;
|
||||
|
@ -363,10 +363,12 @@ probestart(struct cam_periph *periph, union ccb *start_ccb)
|
||||
cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
|
||||
cts.type = CTS_TYPE_CURRENT_SETTINGS;
|
||||
if (path->device->transport == XPORT_ATA) {
|
||||
cts.xport_specific.ata.bytecount = sectors * 512;
|
||||
cts.xport_specific.ata.bytecount = sectors *
|
||||
ata_logical_sector_size(ident_buf);
|
||||
cts.xport_specific.ata.valid = CTS_ATA_VALID_BYTECOUNT;
|
||||
} else {
|
||||
cts.xport_specific.sata.bytecount = sectors * 512;
|
||||
cts.xport_specific.sata.bytecount = sectors *
|
||||
ata_logical_sector_size(ident_buf);
|
||||
cts.xport_specific.sata.valid = CTS_SATA_VALID_BYTECOUNT;
|
||||
}
|
||||
xpt_action((union ccb *)&cts);
|
||||
|
@ -234,7 +234,7 @@ struct ata_params {
|
||||
/*176*/ u_int8_t media_serial[60];
|
||||
/*206*/ u_int16_t sct;
|
||||
u_int16_t reserved206[2];
|
||||
/*209*/ u_int16_t lbalign;
|
||||
/*209*/ u_int16_t lsalign;
|
||||
/*210*/ u_int16_t wrv_sectors_m3_1;
|
||||
u_int16_t wrv_sectors_m3_2;
|
||||
/*212*/ u_int16_t wrv_sectors_m2_1;
|
||||
|
Loading…
Reference in New Issue
Block a user