Overhaul to minimize stack usage, in some places >2K was used

on the stack *blush*...
This commit is contained in:
Søren Schmidt 2001-09-20 15:25:36 +00:00
parent fea451577e
commit f601b4eb7c
18 changed files with 264 additions and 251 deletions

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 1998,1999,2000,2001 Søren Schmidt
* Copyright (c) 1998,1999,2000,2001 Søren Schmidt <sos@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -447,7 +447,6 @@ static int
ata_getparam(struct ata_softc *scp, int device, u_int8_t command)
{
struct ata_params *ata_parm;
int8_t buffer[DEV_BSIZE];
int retry = 0;
/* select drive */
@ -472,14 +471,19 @@ ata_getparam(struct ata_softc *scp, int device, u_int8_t command)
((command == ATA_C_ATAPI_IDENTIFY) ?
ATA_S_DRQ : (ATA_S_READY | ATA_S_DSC | ATA_S_DRQ))));
ATA_INSW(scp->r_io, ATA_DATA, (int16_t *)buffer,
sizeof(buffer)/sizeof(int16_t));
ata_parm = malloc(sizeof(struct ata_params), M_ATA, M_NOWAIT);
if (!ata_parm) {
int i;
for (i = 0; i < sizeof(struct ata_params)/sizeof(int16_t); i++)
ATA_INW(scp->r_io, ATA_DATA);
ata_printf(scp, device, "malloc for identify data failed\n");
return -1;
}
bcopy(buffer, ata_parm, sizeof(struct ata_params));
ATA_INSW(scp->r_io, ATA_DATA, (int16_t *)ata_parm,
sizeof(struct ata_params)/sizeof(int16_t));
if (command == ATA_C_ATA_IDENTIFY ||
!((ata_parm->model[0] == 'N' && ata_parm->model[1] == 'E') ||
(ata_parm->model[0] == 'F' && ata_parm->model[1] == 'X')))
@ -1050,11 +1054,11 @@ out:
}
void
ata_set_name(struct ata_softc *scp, int device, char *name)
ata_set_name(struct ata_softc *scp, int device, char *name, int lun)
{
scp->dev_name[ATA_DEV(device)] = malloc(strlen(name) + 1, M_ATA, M_NOWAIT);
scp->dev_name[ATA_DEV(device)] = malloc(strlen(name) + 4, M_ATA, M_NOWAIT);
if (scp->dev_name[ATA_DEV(device)])
strcpy(scp->dev_name[ATA_DEV(device)], name);
sprintf(scp->dev_name[ATA_DEV(device)], "%s%d", name, lun);
}
void

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 1998,1999,2000,2001 Søren Schmidt
* Copyright (c) 1998,1999,2000,2001 Søren Schmidt <sos@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -211,7 +211,7 @@ int ata_reinit(struct ata_softc *);
int ata_wait(struct ata_softc *, int, u_int8_t);
int ata_command(struct ata_softc *, int, u_int8_t, u_int16_t, u_int8_t, u_int8_t, u_int8_t, u_int8_t, int);
int ata_printf(struct ata_softc *, int, const char *, ...) __printflike(3, 4);
void ata_set_name(struct ata_softc *, int, char *);
void ata_set_name(struct ata_softc *, int, char *, int);
void ata_free_name(struct ata_softc *, int);
int ata_get_lun(u_int32_t *);
int ata_test_lun(u_int32_t *, int);

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 1998,1999,2000,2001 Søren Schmidt
* Copyright (c) 1998,1999,2000,2001 Søren Schmidt <sos@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 1998,1999,2000,2001 Søren Schmidt
* Copyright (c) 1998,1999,2000,2001 Søren Schmidt <sos@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -112,7 +112,6 @@ ad_attach(struct ata_softc *scp, int device)
struct ad_softc *adp;
dev_t dev;
int secsperint;
char name[16];
if (!(adp = malloc(sizeof(struct ad_softc), M_AD, M_NOWAIT | M_ZERO))) {
ata_printf(scp, device, "failed to allocate driver storage\n");
@ -125,8 +124,7 @@ ad_attach(struct ata_softc *scp, int device)
#else
adp->lun = ata_get_lun(&adp_lun_map);
#endif
sprintf(name, "ad%d", adp->lun);
ata_set_name(scp, device, name);
ata_set_name(scp, device, "ad", adp->lun);
adp->heads = AD_PARAM->heads;
adp->sectors = AD_PARAM->sectors;
adp->total_secs = AD_PARAM->cylinders * adp->heads * adp->sectors;

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 1998,1999,2000,2001 Søren Schmidt
* Copyright (c) 1998,1999,2000,2001 Søren Schmidt <sos@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 1998,1999,2000,2001 Søren Schmidt
* Copyright (c) 1998,1999,2000,2001 Søren Schmidt <sos@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 1998,1999,2000,2001 Søren Schmidt
* Copyright (c) 1998,1999,2000,2001 Søren Schmidt <sos@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 1998,1999,2000,2001 Søren Schmidt
* Copyright (c) 1998,1999,2000,2001 Søren Schmidt <sos@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 2000,2001 Søren Schmidt
* Copyright (c) 2000,2001 Søren Schmidt <sos@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -76,7 +76,7 @@ static int ar_read(struct ad_softc *, u_int32_t, int, char *);
/* internal vars */
static int ar_init = 0;
static struct ar_softc *ar_table[8];
static struct ar_softc *ar_table[16];
static MALLOC_DEFINE(M_AR, "AR driver", "ATA RAID driver");
int
@ -290,21 +290,25 @@ done:
static int
ar_highpoint_conf(struct ad_softc *adp, struct ar_softc **raidp)
{
struct highpoint_raid_conf info;
struct highpoint_raid_conf *info;
struct ar_softc *raid;
int array;
int array, error = 1;
if (ar_read(adp, 0x09, DEV_BSIZE, (char *)&info)) {
if (!(info = (struct highpoint_raid_conf *)
malloc(sizeof(struct highpoint_raid_conf), M_AR, M_NOWAIT | M_ZERO)))
return error;
if (ar_read(adp, 0x09, DEV_BSIZE, (char *)info)) {
if (bootverbose)
printf("HighPoint read conf failed\n");
return 1;
goto highpoint_out;
}
/* check if this is a HighPoint RAID struct */
if (info.magic != HPT_MAGIC_OK) {
if (info->magic != HPT_MAGIC_OK) {
if (bootverbose)
printf("HighPoint check1 failed\n");
return 1;
goto highpoint_out;
}
/* now convert HighPoint config info into our generic form */
@ -315,88 +319,88 @@ ar_highpoint_conf(struct ad_softc *adp, struct ar_softc **raidp)
M_NOWAIT | M_ZERO);
if (!raidp[array]) {
printf("ar: failed to allocate raid config storage\n");
return 1;
goto highpoint_out;
}
}
raid = raidp[array];
switch (info.type) {
switch (info->type) {
case HPT_T_RAID_0:
/* check the order byte to determine what this really is */
switch (info.order & (HPT_O_MIRROR | HPT_O_STRIPE)) {
switch (info->order & (HPT_O_MIRROR | HPT_O_STRIPE)) {
case HPT_O_MIRROR:
goto hpt_mirror;
case HPT_O_STRIPE:
if (raid->magic_0 && raid->magic_0 != info.magic_0)
if (raid->magic_0 && raid->magic_0 != info->magic_0)
continue;
raid->magic_0 = info.magic_0;
raid->magic_0 = info->magic_0;
raid->flags |= (AR_F_RAID_0 | AR_F_RAID_1);
raid->interleave = 1 << info.raid0_shift;
raid->subdisk[info.disk_number] = adp;
raid->interleave = 1 << info->raid0_shift;
raid->subdisk[info->disk_number] = adp;
raid->num_subdisks++;
if ((raid->num_subdisks + raid->num_mirrordisks) ==
(info.raid_disks * 2))
(info->raid_disks * 2))
raid->flags |= AR_F_CONF_DONE;
break;
case (HPT_O_MIRROR | HPT_O_STRIPE):
if (raid->magic_1 && raid->magic_1 != info.magic_0)
if (raid->magic_1 && raid->magic_1 != info->magic_0)
continue;
raid->magic_1 = info.magic_0;
raid->magic_1 = info->magic_0;
raid->flags |= (AR_F_RAID_0 | AR_F_RAID_1);
raid->mirrordisk[info.disk_number] = adp;
raid->mirrordisk[info->disk_number] = adp;
raid->num_mirrordisks++;
if ((raid->num_subdisks + raid->num_mirrordisks) ==
(info.raid_disks * 2))
(info->raid_disks * 2))
raid->flags |= AR_F_CONF_DONE;
break;
default:
if (raid->magic_0 && raid->magic_0 != info.magic_0)
if (raid->magic_0 && raid->magic_0 != info->magic_0)
continue;
raid->magic_0 = info.magic_0;
raid->magic_0 = info->magic_0;
raid->flags |= AR_F_RAID_0;
raid->interleave = 1 << info.raid0_shift;
raid->subdisk[info.disk_number] = adp;
raid->interleave = 1 << info->raid0_shift;
raid->subdisk[info->disk_number] = adp;
raid->num_subdisks++;
if (raid->num_subdisks == info.raid_disks)
if (raid->num_subdisks == info->raid_disks)
raid->flags |= AR_F_CONF_DONE;
}
break;
case HPT_T_RAID_1:
hpt_mirror:
if (raid->magic_0 && raid->magic_0 != info.magic_0)
if (raid->magic_0 && raid->magic_0 != info->magic_0)
continue;
raid->magic_0 = info.magic_0;
raid->magic_0 = info->magic_0;
raid->flags |= AR_F_RAID_1;
if (info.disk_number == 0 && raid->num_subdisks == 0) {
if (info->disk_number == 0 && raid->num_subdisks == 0) {
raid->subdisk[raid->num_subdisks] = adp;
raid->num_subdisks = 1;
}
if (info.disk_number != 0 && raid->num_mirrordisks == 0) {
if (info->disk_number != 0 && raid->num_mirrordisks == 0) {
raid->mirrordisk[raid->num_mirrordisks] = adp;
raid->num_mirrordisks = 1;
}
if ((raid->num_subdisks +
raid->num_mirrordisks) == (info.raid_disks * 2))
raid->num_mirrordisks) == (info->raid_disks * 2))
raid->flags |= AR_F_CONF_DONE;
break;
case HPT_T_SPAN:
if (raid->magic_0 && raid->magic_0 != info.magic_0)
if (raid->magic_0 && raid->magic_0 != info->magic_0)
continue;
raid->magic_0 = info.magic_0;
raid->magic_0 = info->magic_0;
raid->flags |= AR_F_SPAN;
raid->subdisk[info.disk_number] = adp;
raid->subdisk[info->disk_number] = adp;
raid->num_subdisks++;
if (raid->num_subdisks == info.raid_disks)
if (raid->num_subdisks == info->raid_disks)
raid->flags |= AR_F_CONF_DONE;
break;
default:
printf("HighPoint unknown RAID type 0x%02x\n", info.type);
printf("HighPoint unknown RAID type 0x%02x\n", info->type);
}
/* do we have a complete array to attach to ? */
@ -404,71 +408,78 @@ hpt_mirror:
raid->lun = array;
raid->heads = 255;
raid->sectors = 63;
raid->cylinders = (info.total_secs - 9) / (63 * 255);
raid->total_secs = info.total_secs - (9 * raid->num_subdisks);
raid->cylinders = (info->total_secs - 9) / (63 * 255);
raid->total_secs = info->total_secs - (9 * raid->num_subdisks);
raid->offset = 10;
raid->reserved = 10;
ar_attach(raid);
}
return 0;
error = 0;
}
return 1;
highpoint_out:
free(info, M_AR);
return error;
}
/* read the RAID info from a disk on a Promise Fasttrak controller */
static int
ar_promise_conf(struct ad_softc *adp, struct ar_softc **raidp)
{
struct promise_raid_conf info;
struct promise_raid_conf *info;
struct ar_softc *raid;
u_int32_t lba, magic;
u_int32_t cksum, *ckptr;
int count, disk_number, array;
int count, disk_number, array, error = 1;
if (!(info = (struct promise_raid_conf *)
malloc(sizeof(struct promise_raid_conf), M_AR, M_NOWAIT | M_ZERO)))
return error;
lba = ((adp->total_secs / (adp->heads * adp->sectors)) *
adp->heads * adp->sectors) - adp->sectors;
if (ar_read(adp, lba, 4 * DEV_BSIZE, (char *)&info)) {
if (ar_read(adp, lba, 4 * DEV_BSIZE, (char *)info)) {
if (bootverbose)
printf("Promise read conf failed\n");
return 1;
goto promise_out;
}
/* check if this is a Promise RAID struct */
if (strncmp(info.promise_id, PR_MAGIC, sizeof(PR_MAGIC))) {
if (strncmp(info->promise_id, PR_MAGIC, sizeof(PR_MAGIC))) {
if (bootverbose)
printf("Promise check1 failed\n");
return 1;
goto promise_out;
}
/* check if the checksum is OK */
for (cksum = 0, ckptr = (int32_t *)&info, count = 0; count < 511; count++)
for (cksum = 0, ckptr = (int32_t *)info, count = 0; count < 511; count++)
cksum += *ckptr++;
if (cksum != *ckptr) {
if (bootverbose)
printf("Promise check2 failed\n");
return 1;
goto promise_out;
}
/* now convert Promise config info into our generic form */
if ((info.raid.flags != PR_F_CONFED) ||
(((info.raid.status & (PR_S_DEFINED|PR_S_ONLINE)) !=
if ((info->raid.flags != PR_F_CONFED) ||
(((info->raid.status & (PR_S_DEFINED|PR_S_ONLINE)) !=
(PR_S_DEFINED|PR_S_ONLINE)))) {
return 1;
goto promise_out;
}
magic = (adp->controller->chiptype >> 16) | info.raid.array_number << 16;
magic = (adp->controller->chiptype >> 16) | info->raid.array_number << 16;
array = info.raid.array_number;
array = info->raid.array_number;
if (raidp[array]) {
if (magic != raidp[array]->magic_0)
return 1;
goto promise_out;
}
else {
if (!(raidp[array] = (struct ar_softc *)
malloc(sizeof(struct ar_softc), M_AR, M_NOWAIT))) {
printf("ar: failed to allocate raid config storage\n");
return 1;
goto promise_out;
}
else
bzero(raidp[array], sizeof(struct ar_softc));
@ -476,10 +487,10 @@ ar_promise_conf(struct ad_softc *adp, struct ar_softc **raidp)
raid = raidp[array];
raid->magic_0 = magic;
switch (info.raid.type) {
switch (info->raid.type) {
case PR_T_STRIPE:
raid->flags |= AR_F_RAID_0;
raid->interleave = 1 << info.raid.raid0_shift;
raid->interleave = 1 << info->raid.raid0_shift;
break;
case PR_T_MIRROR:
@ -491,38 +502,42 @@ ar_promise_conf(struct ad_softc *adp, struct ar_softc **raidp)
break;
default:
printf("Promise unknown RAID type 0x%02x\n", info.raid.type);
return 1;
printf("Promise unknown RAID type 0x%02x\n", info->raid.type);
goto promise_out;
}
/* find out where this disk is in the defined array */
disk_number = info.raid.disk_number;
if (disk_number < info.raid.raid0_disks) {
disk_number = info->raid.disk_number;
if (disk_number < info->raid.raid0_disks) {
raid->subdisk[disk_number] = adp;
raid->num_subdisks++;
if (raid->num_subdisks > 1 && !(raid->flags & AR_F_SPAN)) {
raid->flags |= AR_F_RAID_0;
raid->interleave = 1 << info.raid.raid0_shift;
raid->interleave = 1 << info->raid.raid0_shift;
}
}
else {
raid->mirrordisk[disk_number - info.raid.raid0_disks] = adp;
raid->mirrordisk[disk_number - info->raid.raid0_disks] = adp;
raid->num_mirrordisks++;
}
/* do we have a complete array to attach to ? */
if (raid->num_subdisks + raid->num_mirrordisks == info.raid.total_disks) {
if (raid->num_subdisks + raid->num_mirrordisks == info->raid.total_disks) {
raid->flags |= AR_F_CONF_DONE;
raid->lun = array;
raid->heads = info.raid.heads + 1;
raid->sectors = info.raid.sectors;
raid->cylinders = info.raid.cylinders + 1;
raid->total_secs = info.raid.total_secs;
raid->heads = info->raid.heads + 1;
raid->sectors = info->raid.sectors;
raid->cylinders = info->raid.cylinders + 1;
raid->total_secs = info->raid.total_secs;
raid->offset = 0;
raid->reserved = 63;
ar_attach(raid);
}
return 0;
error = 0;
promise_out:
free(info, M_AR);
return error;
}
int

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 2000,2001 Søren Schmidt
* Copyright (c) 2000,2001 Søren Schmidt <sos@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 1998,1999,2000,2001 Søren Schmidt
* Copyright (c) 1998,1999,2000,2001 Søren Schmidt <sos@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 1998,1999,2000,2001 Søren Schmidt
* Copyright (c) 1998,1999,2000,2001 Søren Schmidt <sos@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 1998,1999,2000,2001 Søren Schmidt
* Copyright (c) 1998,1999,2000,2001 Søren Schmidt <sos@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -109,7 +109,6 @@ acdattach(struct atapi_softc *atp)
{
struct acd_softc *cdp;
struct changer *chp;
char name[16];
static int acd_cdev_done = 0;
if (!acd_cdev_done) {
@ -122,8 +121,7 @@ acdattach(struct atapi_softc *atp)
return -1;
}
sprintf(name, "acd%d", cdp->lun);
ata_set_name(atp->controller, atp->unit, name);
ata_set_name(atp->controller, atp->unit, "acd", cdp->lun);
acd_get_cap(cdp);
/* if this is a changer device, allocate the neeeded lun's */
@ -144,6 +142,7 @@ acdattach(struct atapi_softc *atp)
ATPR_F_READ, 60, NULL, NULL)) {
struct acd_softc *tmpcdp = cdp;
struct acd_softc **cdparr;
char *name;
int count;
chp->table_length = htons(chp->table_length);
@ -156,7 +155,7 @@ acdattach(struct atapi_softc *atp)
}
for (count = 0; count < chp->slots; count++) {
if (count > 0) {
tmpcdp = acd_init_lun(atp, cdp->stats);
tmpcdp = acd_init_lun(atp, NULL);
if (!tmpcdp) {
ata_printf(atp->controller,atp->unit,"out of memory\n");
break;
@ -167,15 +166,19 @@ acdattach(struct atapi_softc *atp)
tmpcdp->slot = count;
tmpcdp->changer_info = chp;
acd_make_dev(tmpcdp);
devstat_add_entry(cdp->stats, "acd", tmpcdp->lun, DEV_BSIZE,
DEVSTAT_NO_ORDERED_TAGS,
DEVSTAT_TYPE_CDROM | DEVSTAT_TYPE_IF_IDE,
DEVSTAT_PRIORITY_CD);
}
sprintf(name, "acd%d-%d", cdp->lun,
cdp->lun + cdp->changer_info->slots - 1);
name =
malloc(strlen(atp->controller->dev_name[ATA_DEV(atp->unit)])+1,
M_ACD, M_NOWAIT);
strcpy(name, atp->controller->dev_name[ATA_DEV(atp->unit)]);
ata_free_name(atp->controller, atp->unit);
ata_set_name(atp->controller, atp->unit, name);
devstat_add_entry(cdp->stats, name, tmpcdp->lun, DEV_BSIZE,
DEVSTAT_NO_ORDERED_TAGS,
DEVSTAT_TYPE_CDROM | DEVSTAT_TYPE_IF_IDE,
DEVSTAT_PRIORITY_CD);
ata_set_name(atp->controller, atp->unit, name,
cdp->lun + cdp->changer_info->slots - 1);
free(name, M_ACD);
}
}
else {
@ -460,24 +463,21 @@ acd_describe(struct acd_softc *cdp)
}
}
else {
char chg[32];
bzero(chg, sizeof(chg));
if (cdp->changer_info)
sprintf(chg, " with %d CD changer", cdp->changer_info->slots);
ata_printf(cdp->atp->controller, cdp->atp->unit,
"%s%s <%.40s> at ata%d-%s %s\n",
ata_printf(cdp->atp->controller, cdp->atp->unit, "%s ",
(cdp->cap.write_dvdr) ? "DVD-R" :
(cdp->cap.write_dvdram) ? "DVD-RAM" :
(cdp->cap.write_cdrw) ? "CD-RW" :
(cdp->cap.write_cdr) ? "CD-R" :
(cdp->cap.read_dvdrom) ? "DVD-ROM" : "CDROM",
chg, ATA_PARAM(cdp->atp->controller, cdp->atp->unit)->model,
device_get_unit(cdp->atp->controller->dev),
(cdp->atp->unit == ATA_MASTER) ? "master" : "slave",
ata_mode2str(cdp->atp->controller->
mode[ATA_DEV(cdp->atp->unit)])
(cdp->cap.read_dvdrom) ? "DVD-ROM" : "CDROM");
if (cdp->changer_info)
printf("with %d CD changer ", cdp->changer_info->slots);
printf("<%.40s> at ata%d-%s %s\n",
ATA_PARAM(cdp->atp->controller, cdp->atp->unit)->model,
device_get_unit(cdp->atp->controller->dev),
(cdp->atp->unit == ATA_MASTER) ? "master" : "slave",
ata_mode2str(cdp->atp->controller->mode[ATA_DEV(cdp->atp->unit)])
);
}
}
@ -628,11 +628,10 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct thread *td)
{
struct ioc_read_toc_entry *te = (struct ioc_read_toc_entry *)addr;
struct toc *toc = &cdp->toc;
struct toc buf;
int starting_track = te->starting_track;
int len;
if (!cdp->toc.hdr.ending_track) {
if (!toc->hdr.ending_track) {
error = EIO;
break;
}
@ -667,8 +666,8 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct thread *td)
if (te->address_format == CD_MSF_FORMAT) {
struct cd_toc_entry *entry;
buf = cdp->toc;
toc = &buf;
toc = malloc(sizeof(struct toc), M_ACD, M_NOWAIT | M_ZERO);
bcopy(&cdp->toc, toc, sizeof(struct toc));
entry = toc->tab + (toc->hdr.ending_track + 1 -
toc->hdr.starting_track) + 1;
while (--entry >= toc->tab)
@ -677,6 +676,8 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct thread *td)
}
error = copyout(toc->tab + starting_track - toc->hdr.starting_track,
te->data, len);
if (te->address_format == CD_MSF_FORMAT)
free(toc, M_ACD);
break;
}
case CDIOREADTOCENTRY:
@ -684,10 +685,9 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct thread *td)
struct ioc_read_toc_single_entry *te =
(struct ioc_read_toc_single_entry *)addr;
struct toc *toc = &cdp->toc;
struct toc buf;
u_char track = te->track;
if (!cdp->toc.hdr.ending_track) {
if (!toc->hdr.ending_track) {
error = EIO;
break;
}
@ -711,14 +711,17 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct thread *td)
if (te->address_format == CD_MSF_FORMAT) {
struct cd_toc_entry *entry;
buf = cdp->toc;
toc = &buf;
toc = malloc(sizeof(struct toc), M_ACD, M_NOWAIT | M_ZERO);
bcopy(&cdp->toc, toc, sizeof(struct toc));
entry = toc->tab + (track - toc->hdr.starting_track);
lba2msf(ntohl(entry->addr.lba), &entry->addr.msf.minute,
&entry->addr.msf.second, &entry->addr.msf.frame);
}
bcopy(toc->tab + track - toc->hdr.starting_track,
&te->entry, sizeof(struct cd_toc_entry));
if (te->address_format == CD_MSF_FORMAT)
free(toc, M_ACD);
}
break;
@ -726,15 +729,13 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct thread *td)
{
struct ioc_read_subchannel *args =
(struct ioc_read_subchannel *)addr;
struct cd_sub_channel_info data;
int len = args->data_len;
int32_t abslba, rellba;
struct cd_sub_channel_info *data;
int8_t ccb[16] = { ATAPI_READ_SUBCHANNEL, 0, 0x40, 1, 0, 0, 0,
sizeof(cdp->subchan)>>8, sizeof(cdp->subchan),
0, 0, 0, 0, 0, 0, 0 };
if (len > sizeof(data) ||
len < sizeof(struct cd_sub_channel_header)) {
if (args->data_len > sizeof(data) ||
args->data_len < sizeof(struct cd_sub_channel_header)) {
error = EINVAL;
break;
}
@ -744,27 +745,29 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct thread *td)
NULL, NULL))) {
break;
}
abslba = cdp->subchan.abslba;
rellba = cdp->subchan.rellba;
data = malloc(sizeof(struct cd_sub_channel_info),
M_ACD, M_NOWAIT | M_ZERO);
if (args->address_format == CD_MSF_FORMAT) {
lba2msf(ntohl(abslba),
&data.what.position.absaddr.msf.minute,
&data.what.position.absaddr.msf.second,
&data.what.position.absaddr.msf.frame);
lba2msf(ntohl(rellba),
&data.what.position.reladdr.msf.minute,
&data.what.position.reladdr.msf.second,
&data.what.position.reladdr.msf.frame);
lba2msf(ntohl(cdp->subchan.abslba),
&data->what.position.absaddr.msf.minute,
&data->what.position.absaddr.msf.second,
&data->what.position.absaddr.msf.frame);
lba2msf(ntohl(cdp->subchan.rellba),
&data->what.position.reladdr.msf.minute,
&data->what.position.reladdr.msf.second,
&data->what.position.reladdr.msf.frame);
} else {
data.what.position.absaddr.lba = abslba;
data.what.position.reladdr.lba = rellba;
data->what.position.absaddr.lba = cdp->subchan.abslba;
data->what.position.reladdr.lba = cdp->subchan.rellba;
}
data.header.audio_status = cdp->subchan.audio_status;
data.what.position.control = cdp->subchan.control & 0xf;
data.what.position.addr_type = cdp->subchan.control >> 4;
data.what.position.track_number = cdp->subchan.track;
data.what.position.index_number = cdp->subchan.indx;
error = copyout(&data, args->data, len);
data->header.audio_status = cdp->subchan.audio_status;
data->what.position.control = cdp->subchan.control & 0xf;
data->what.position.addr_type = cdp->subchan.control >> 4;
data->what.position.track_number = cdp->subchan.track;
data->what.position.index_number = cdp->subchan.indx;
error = copyout(data, args->data, args->data_len);
free(data, M_ACD);
break;
}
@ -1125,7 +1128,6 @@ acd_start(struct atapi_softc *atp)
/* reject all queued entries if media changed */
if (cdp->atp->flags & ATAPI_F_MEDIA_CHANGED) {
printf("reject due to media change\n");
biofinish(bp, NULL, EIO);
return;
}
@ -1643,11 +1645,7 @@ acd_send_cue(struct acd_softc *cdp, struct cdr_cuesheet *cuesheet)
static int
acd_report_key(struct acd_softc *cdp, struct dvd_authinfo *ai)
{
struct {
u_int16_t length;
u_char reserved[2];
u_char data[12];
} d;
struct dvd_miscauth *d;
u_int32_t lba = 0;
int16_t length;
int8_t ccb[16];
@ -1685,82 +1683,85 @@ acd_report_key(struct acd_softc *cdp, struct dvd_authinfo *ai)
ccb[8] = (length >> 8) & 0xff;
ccb[9] = length & 0xff;
ccb[10] = (ai->agid << 6) | ai->format;
bzero(&d, sizeof(d));
d.length = htons(length - 2);
error = atapi_queue_cmd(cdp->atp, ccb, (caddr_t)&d, length,
d = malloc(length, M_ACD, M_NOWAIT | M_ZERO);
d->length = htons(length - 2);
error = atapi_queue_cmd(cdp->atp, ccb, (caddr_t)d, length,
ai->format == DVD_INVALIDATE_AGID ? 0 : ATPR_F_READ,
10, NULL, NULL);
if (error)
if (error) {
free(d, M_ACD);
return error;
}
switch (ai->format) {
case DVD_REPORT_AGID:
ai->agid = d.data[3] >> 6;
ai->agid = d->data[3] >> 6;
break;
case DVD_REPORT_CHALLENGE:
bcopy(&d.data[0], &ai->keychal[0], 10);
bcopy(&d->data[0], &ai->keychal[0], 10);
break;
case DVD_REPORT_KEY1:
bcopy(&d.data[0], &ai->keychal[0], 5);
bcopy(&d->data[0], &ai->keychal[0], 5);
break;
case DVD_REPORT_TITLE_KEY:
ai->cpm = (d.data[0] >> 7);
ai->cp_sec = (d.data[0] >> 6) & 0x1;
ai->cgms = (d.data[0] >> 4) & 0x3;
bcopy(&d.data[1], &ai->keychal[0], 5);
ai->cpm = (d->data[0] >> 7);
ai->cp_sec = (d->data[0] >> 6) & 0x1;
ai->cgms = (d->data[0] >> 4) & 0x3;
bcopy(&d->data[1], &ai->keychal[0], 5);
break;
case DVD_REPORT_ASF:
ai->asf = d.data[3] & 1;
ai->asf = d->data[3] & 1;
break;
case DVD_REPORT_RPC:
ai->reg_type = (d.data[0] >> 6);
ai->vend_rsts = (d.data[0] >> 3) & 0x7;
ai->user_rsts = d.data[0] & 0x7;
ai->region = d.data[1];
ai->rpc_scheme = d.data[2];
ai->reg_type = (d->data[0] >> 6);
ai->vend_rsts = (d->data[0] >> 3) & 0x7;
ai->user_rsts = d->data[0] & 0x7;
ai->region = d->data[1];
ai->rpc_scheme = d->data[2];
break;
case DVD_INVALIDATE_AGID:
break;
default:
return EINVAL;
error = EINVAL;
}
return 0;
free(d, M_ACD);
return error;
}
static int
acd_send_key(struct acd_softc *cdp, struct dvd_authinfo *ai)
{
struct {
u_int16_t length;
u_char reserved[2];
u_char data[12];
} d;
struct dvd_miscauth *d;
int16_t length;
int8_t ccb[16];
bzero(&d, sizeof(d));
int error;
switch (ai->format) {
case DVD_SEND_CHALLENGE:
length = 16;
bcopy(ai->keychal, &d.data[0], 10);
d = malloc(length, M_ACD, M_NOWAIT | M_ZERO);
bcopy(ai->keychal, &d->data[0], 10);
break;
case DVD_SEND_KEY2:
length = 12;
bcopy(&ai->keychal[0], &d.data[0], 5);
d = malloc(length, M_ACD, M_NOWAIT | M_ZERO);
bcopy(&ai->keychal[0], &d->data[0], 5);
break;
case DVD_SEND_RPC:
length = 8;
d.data[0] = ai->region;
d = malloc(length, M_ACD, M_NOWAIT | M_ZERO);
d->data[0] = ai->region;
break;
default:
@ -1772,24 +1773,20 @@ acd_send_key(struct acd_softc *cdp, struct dvd_authinfo *ai)
ccb[8] = (length >> 8) & 0xff;
ccb[9] = length & 0xff;
ccb[10] = (ai->agid << 6) | ai->format;
d.length = htons(length - 2);
return atapi_queue_cmd(cdp->atp, ccb, (caddr_t)&d, length, 0,
10, NULL, NULL);
d->length = htons(length - 2);
error = atapi_queue_cmd(cdp->atp, ccb, (caddr_t)d, length, 0,
10, NULL, NULL);
free(d, M_ACD);
return error;
}
static int
acd_read_structure(struct acd_softc *cdp, struct dvd_struct *s)
{
struct {
u_int16_t length;
u_char reserved[2];
u_char data[2048];
} d;
struct dvd_miscauth *d;
u_int16_t length;
int error = 0;
int8_t ccb[16];
bzero(&d, sizeof(d));
int error = 0;
switch(s->format) {
case DVD_STRUCT_PHYSICAL:
@ -1826,6 +1823,9 @@ acd_read_structure(struct acd_softc *cdp, struct dvd_struct *s)
return EINVAL;
}
d = malloc(length, M_ACD, M_NOWAIT | M_ZERO);
d->length = htons(length - 2);
bzero(ccb, sizeof(ccb));
ccb[0] = ATAPI_READ_STRUCTURE;
ccb[6] = s->layer_num;
@ -1833,55 +1833,57 @@ acd_read_structure(struct acd_softc *cdp, struct dvd_struct *s)
ccb[8] = (length >> 8) & 0xff;
ccb[9] = length & 0xff;
ccb[10] = s->agid << 6;
d.length = htons(length - 2);
error = atapi_queue_cmd(cdp->atp, ccb, (caddr_t)&d, length, ATPR_F_READ,
error = atapi_queue_cmd(cdp->atp, ccb, (caddr_t)d, length, ATPR_F_READ,
30, NULL, NULL);
if (error)
if (error) {
free(d, M_ACD);
return error;
}
switch (s->format) {
case DVD_STRUCT_PHYSICAL: {
struct dvd_layer *layer = (struct dvd_layer *)&s->data[0];
layer->book_type = d.data[0] >> 4;
layer->book_version = d.data[0] & 0xf;
layer->disc_size = d.data[1] >> 4;
layer->max_rate = d.data[1] & 0xf;
layer->nlayers = (d.data[2] >> 5) & 3;
layer->track_path = (d.data[2] >> 4) & 1;
layer->layer_type = d.data[2] & 0xf;
layer->linear_density = d.data[3] >> 4;
layer->track_density = d.data[3] & 0xf;
layer->start_sector = d.data[5] << 16 | d.data[6] << 8 | d.data[7];
layer->end_sector = d.data[9] << 16 | d.data[10] << 8 | d.data[11];
layer->end_sector_l0 = d.data[13] << 16 | d.data[14] << 8 | d.data[15];
layer->bca = d.data[16] >> 7;
layer->book_type = d->data[0] >> 4;
layer->book_version = d->data[0] & 0xf;
layer->disc_size = d->data[1] >> 4;
layer->max_rate = d->data[1] & 0xf;
layer->nlayers = (d->data[2] >> 5) & 3;
layer->track_path = (d->data[2] >> 4) & 1;
layer->layer_type = d->data[2] & 0xf;
layer->linear_density = d->data[3] >> 4;
layer->track_density = d->data[3] & 0xf;
layer->start_sector = d->data[5] << 16 | d->data[6] << 8 | d->data[7];
layer->end_sector = d->data[9] << 16 | d->data[10] << 8 | d->data[11];
layer->end_sector_l0 = d->data[13] << 16 | d->data[14] << 8|d->data[15];
layer->bca = d->data[16] >> 7;
break;
}
case DVD_STRUCT_COPYRIGHT:
s->cpst = d.data[0];
s->rmi = d.data[0];
s->cpst = d->data[0];
s->rmi = d->data[0];
break;
case DVD_STRUCT_DISCKEY:
bcopy(&d.data[0], &s->data[0], 2048);
bcopy(&d->data[0], &s->data[0], 2048);
break;
case DVD_STRUCT_BCA:
s->length = ntohs(d.length);
bcopy(&d.data[0], &s->data[0], s->length);
s->length = ntohs(d->length);
bcopy(&d->data[0], &s->data[0], s->length);
break;
case DVD_STRUCT_MANUFACT:
s->length = ntohs(d.length);
bcopy(&d.data[0], &s->data[0], s->length);
s->length = ntohs(d->length);
bcopy(&d->data[0], &s->data[0], s->length);
break;
default:
return EINVAL;
error = EINVAL;
}
return 0;
free(d, M_ACD);
return error;
}
static int

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 1998,1999,2000,2001 Søren Schmidt
* Copyright (c) 1998,1999,2000,2001 Søren Schmidt <sos@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -35,6 +35,13 @@ struct toc {
struct cd_toc_entry tab[MAXTRK + 1];
};
/* DVD CSS authentication */
struct dvd_miscauth {
u_int16_t length;
u_int16_t reserved;
u_int8_t data[2048];
};
/* CDROM Audio Control Parameters Page */
struct audiopage {
/* mode page data header */

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 1998,1999,2000,2001 Søren Schmidt
* Copyright (c) 1998,1999,2000,2001 Søren Schmidt <sos@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -83,7 +83,6 @@ afdattach(struct atapi_softc *atp)
{
struct afd_softc *fdp;
dev_t dev;
char name[16];
fdp = malloc(sizeof(struct afd_softc), M_AFD, M_NOWAIT | M_ZERO);
if (!fdp) {
@ -93,8 +92,7 @@ afdattach(struct atapi_softc *atp)
fdp->atp = atp;
fdp->lun = ata_get_lun(&afd_lun_map);
sprintf(name, "afd%d", fdp->lun);
ata_set_name(atp->controller, atp->unit, name);
ata_set_name(atp->controller, atp->unit, "afd", fdp->lun);
bioq_init(&fdp->queue);
if (afd_sense(fdp)) {
@ -140,10 +138,9 @@ afddetach(struct atapi_softc *atp)
static int
afd_sense(struct afd_softc *fdp)
{
int8_t buffer[256];
int8_t ccb[16] = { ATAPI_MODE_SENSE_BIG, 0, ATAPI_REWRITEABLE_CAP_PAGE,
0, 0, 0, 0, sizeof(buffer)>>8, sizeof(buffer) & 0xff,
0, 0, 0, 0, 0, 0, 0 };
0, 0, 0, 0, sizeof(struct afd_cappage) >> 8,
sizeof(struct afd_cappage) & 0xff, 0, 0, 0, 0, 0, 0, 0 };
int count, error = 0;
/* The IOMEGA Clik! doesn't support reading the cap page, fake it */
@ -159,19 +156,14 @@ afd_sense(struct afd_softc *fdp)
return 0;
}
bzero(buffer, sizeof(buffer));
/* get drive capabilities, some drives needs this repeated */
for (count = 0 ; count < 5 ; count++) {
if (!(error = atapi_queue_cmd(fdp->atp, ccb, buffer, sizeof(buffer),
if (!(error = atapi_queue_cmd(fdp->atp, ccb, (caddr_t)&fdp->cap,
sizeof(struct afd_cappage),
ATPR_F_READ, 30, NULL, NULL)))
break;
}
if (error)
return error;
bcopy(buffer, &fdp->header, sizeof(struct afd_header));
bcopy(buffer + sizeof(struct afd_header), &fdp->cap,
sizeof(struct afd_cappage));
if (fdp->cap.page_code != ATAPI_REWRITEABLE_CAP_PAGE)
if (error || fdp->cap.page_code != ATAPI_REWRITEABLE_CAP_PAGE)
return 1;
fdp->cap.cylinders = ntohs(fdp->cap.cylinders);
fdp->cap.sector_size = ntohs(fdp->cap.sector_size);
@ -202,9 +194,9 @@ afd_describe(struct afd_softc *fdp)
printf(" transfer limit %d blks,", fdp->transfersize);
printf(" %s\n", ata_mode2str(fdp->atp->controller->mode[
ATA_DEV(fdp->atp->unit)]));
if (fdp->header.medium_type) {
if (fdp->cap.medium_type) {
ata_printf(fdp->atp->controller, fdp->atp->unit, "Medium: ");
switch (fdp->header.medium_type) {
switch (fdp->cap.medium_type) {
case MFD_2DD:
printf("720KB DD disk"); break;
@ -218,16 +210,16 @@ afd_describe(struct afd_softc *fdp)
printf("120MB UHD disk"); break;
default:
printf("Unknown (0x%x)", fdp->header.medium_type);
printf("Unknown (0x%x)", fdp->cap.medium_type);
}
if (fdp->header.wp) printf(", writeprotected");
if (fdp->cap.wp) printf(", writeprotected");
}
printf("\n");
}
else {
ata_printf(fdp->atp->controller, fdp->atp->unit,
"%luMB <%.40s> [%d/%d/%d] at ata%d-%s %s\n",
(fdp->cap.cylinders*fdp->cap.heads*fdp->cap.sectors) /
(fdp->cap.cylinders * fdp->cap.heads * fdp->cap.sectors) /
((1024L * 1024L) / fdp->cap.sector_size),
ATA_PARAM(fdp->atp->controller, fdp->atp->unit)->model,
fdp->cap.cylinders, fdp->cap.heads, fdp->cap.sectors,

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 1998,1999,2000,2001 Søren Schmidt
* Copyright (c) 1998,1999,2000,2001 Søren Schmidt <sos@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -28,8 +28,8 @@
* $FreeBSD$
*/
/* MODE SENSE parameter header */
struct afd_header {
/* ATAPI Rewriteable drive Capabilities and Mechanical Status Page */
struct afd_cappage {
u_int16_t data_length;
u_int8_t medium_type;
#define MFD_2DD_UN 0x10
@ -48,10 +48,8 @@ struct afd_header {
u_int8_t reserved0 :7;
u_int8_t wp :1; /* write protect */
u_int8_t unused[4];
};
/* ATAPI Rewriteable drive Capabilities and Mechanical Status Page */
struct afd_cappage {
/* capabilities page */
u_int8_t page_code :6;
#define ATAPI_REWRITEABLE_CAP_PAGE 0x05
@ -75,7 +73,6 @@ struct afd_softc {
int lun; /* logical device unit */
int transfersize; /* max size of each transfer */
struct bio_queue_head queue; /* queue of i/o requests */
struct afd_header header; /* capabilities page info */
struct afd_cappage cap; /* capabilities page info */
struct disk disk; /* virtual drives */
struct devstat stats;

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 1998,1999,2000,2001 Søren Schmidt
* Copyright (c) 1998,1999,2000,2001 Søren Schmidt <sos@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -90,7 +90,6 @@ astattach(struct atapi_softc *atp)
struct ast_softc *stp;
struct ast_readposition position;
dev_t dev;
char name[16];
static int ast_cdev_done = 0;
if (!ast_cdev_done) {
@ -106,8 +105,7 @@ astattach(struct atapi_softc *atp)
stp->atp = atp;
stp->lun = ata_get_lun(&ast_lun_map);
sprintf(name, "ast%d", stp->lun);
ata_set_name(atp->controller, atp->unit, name);
ata_set_name(atp->controller, atp->unit, "ast", stp->lun);
bioq_init(&stp->queue);
if (ast_sense(stp)) {

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 1998,1999,2000,2001 Søren Schmidt
* Copyright (c) 1998,1999,2000,2001 Søren Schmidt <sos@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without