Overhaul to minimize stack usage, in some places >2K was used
on the stack *blush*...
This commit is contained in:
parent
fea451577e
commit
f601b4eb7c
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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)) {
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user