Arch-handbook, scsi-general, typos in XPT_CALC_GEOMETRY?
Alexey Illarionov
littlesavage at rambler.ru
Tue Nov 22 00:18:13 UTC 2005
http://www.freebsd.org/doc/en_US.ISO8859-1/books/arch-handbook/scsi-general.html
Quote:
XPT_CALC_GEOMETRY - calculate logical (BIOS) geometry of the disk
The arguments are transferred in the instance “struct ccb_calc_geometry ccg” of the union ccb:
* block_size - input, block (A.K.A sector) size in bytes
* volume_size - input, volume size in bytes (???)
* cylinders - output, logical cylinders
* heads - output, logical heads
* secs_per_track - output, logical sectors per track
<skip>
The typical calculation example taken from the aic7xxx driver is:
struct ccb_calc_geometry *ccg;
u_int32_t size_mb;
u_int32_t secs_per_cylinder;
int extended;
ccg = &ccb->ccg;
size_mb = ccg->volume_size
/ ((1024L * 1024L) / ccg->block_size);
extended = check_cards_EEPROM_for_extended_geometry(softc);
<skip>
The volume_size argument whether really it is the size of volume in bytes or in sectors?
If it in bytes, how it seems to me, the variable size_mb is calculated not correctly
( should be size_mb = ccg->volume_size / (1024L * 1024L) )
If it in sectors it calculated not correctly too.
It can cause division by zero, if ccg->block_size will be more than one mbyte ( > 1024L * 1024L)
I understand, that it is almost impossible, but I get this in result of different error (usb/73307).
If I remember arithmetics,
ccg->volume_size / ((1024L * 1024L) / ccg->block_size) ==
ccg->volume_size * ((ccg->block_size / (1024L * 1024L)) ==
(ccg->volume_size * ccg->block_size) / (1024L * 1024L)
Such formula is more intuitively clear and will not cause division by zero. It is only necessary
for (ccg->volume_size * ccg->block_size) to use u_int64_t or manually check for overflows
Besides aic7xxx driver now have this code:
#if __FreeBSD_version >= 500000
cam_calc_geometry(ccg, extended);
#else
...
I think, it can be added to this part of handbook. What do you think about this?
More information about the freebsd-doc
mailing list