linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* RE: devicefs requests
@ 2002-09-26 16:13 Matt_Domsch
  2002-09-27  4:41 ` Greg KH
  0 siblings, 1 reply; 13+ messages in thread
From: Matt_Domsch @ 2002-09-26 16:13 UTC (permalink / raw)
  To: greg, mdharm-usb; +Cc: mochel, linux-kernel

> What are you trying to walk all of the USB devices for?  What would you
> do if you found a USB mass storage device that matched something in the
> EDD tables?

My goal is simple, my approach may be flawed. :-)
x86 BIOS decides somehow what disk to boot from.  In a single disk system,
that's a pretty simple choice.  In a multi-disk system, BIOSs (either
on-board or add-in cards) enumerate devices and hook them to the int13
vector, and the system boots from device 80h, the first hard disk detected
and hooked to that vector.  Problem is, Linux doesn't have a way to know
which disk BIOS thinks is the boot disk.  Think installing onto a brand new
system with no data on any of its 8 internal disks, split across multiple
SCSI controllers, with an add-in RAID controller connecting a pile of
external storage.  The Linux installer (at least) needs to know on which
disk to put lilo/grub in order to boot, and would like a hint as to where to
put /boot and / file systems, and right now that requires human intervention
and guesses - it's entirely possible to install on to such a system, reboot,
and the boot loader didn't get placed where BIOS goes to look for it.  I've
got to restrict our factory preload configurations because of this.


EDD 3.0 is supposed to help solve this.  We query BIOS early in the boot
process before switching to protected mode and store away the device path
information on a per-disk basis.  I want to use this device path information
(PCI bus:dev.fn, {SCSI bus,id,lun; IDE controller,dev; USB - spec says
serial number); ...})  to compare against what the devices themselves
believe they're at under Linux, and provide a symlink in driverfs from a
BIOS device item to the Linux device item.  Userspace hotplug will create
/dev/sdX by getting information from driverfs, and userspace tools like boot
loader installers could follow the symlink, get the kdev, make a temporary
device node, and operate on the right disk.  (Temporary because it could
change on next boot if controllers or disks are are added/removed).

What I'm picturing is something like this (feedback welcome!):

/driverfs/
|-- bus
|   |-- scsi
|   |   |-- devices
|   |   |   |-- 0:0:0:0 -> ../../../root/pci2/02:06.0/scsi0/0:0:0:0
|   |   |   |-- 0:0:0:0:disc ->
../../../root/pci2/02:06.0/scsi0/0:0:0:0/0:0:0:0:disc
|   |   |   `-- 2:0:5:0 -> ../../../root/pci0/00:02.0/01:06.0/scsi2/2:0:5:0
|   |   |   `-- 2:0:5:0:disc ->
../../../root/pci0/00:02.0/01:06.0/scsi2/2:0:5:0:disc
|   |   `-- drivers
|   |       `-- sd
`-- root
    |-- BIOS_int13
    |   |-- 80
    |   |   |-- disc -> ../../pci2/02:06.0/scsi0/0:0:0:0/0:0:0:0:disc/kdev
    |   |   `-- info
    |   |-- 81
    |   |   |-- disc -> ../../pci2/02:06.0/scsi0/2:0:5:0/2:0:5:0:disc/kdev
    |   |   `-- info
    |-- pci2
    |   |-- 02:06.0
    |   |   |-- irq
    |   |   |-- name
    |   |   |-- power
    |   |   |-- resource
    |   |   `-- scsi0
    |   |       |-- 0:0:0:0
    |   |       |   |-- 0:0:0:0:disc
    |   |       |   |   |-- kdev


The only reason I'm doing even this much in driverfs is because I thought
the symlink idea would be nice.  I could just as easily export two files per
BIOS device: interface_path and device_path, and make userspace read those
and walk the driverfs tree looking for the match.  I was hoping that
driverfs could display this relationship between devices as it already does
for PCI {SCSI,IDE,...} devices.  If I can't walk the list of devices from
inside the kernel looking for a match, I'll do it in userspace.

So far I've focused on SCSI because that's the type that can be most easily
constructed into really wierd controller and disk configurations, and what
we sell most of in our servers.  Once SCSI works, I think IDE will follow
pretty easily.  The EDD spec allows for a wide variety of interface paths:
ISA, PCI, PCI-X, InfiniBand, PCI Express, HyperTransport; and device paths:
ATA, ATAPI, SCSI, USB, 1394, Fibre, I2O, RAID, SATA.  

> It seems that this spec is oriented toward storage devices.  The USB
> device structure if for all types of devices.

Yes, the EDD spec is all about storage devices, particularly x86 BIOS int13
devices.  I'm less worried about non-disk devices right now, I'm concerned
about being able to boot from disk devices.

> As for USB storage devices, I don't know if they all contain serial
> numbers that are unique, you might want to go ask the author of the
> usb-storage driver, Matt Dharm.

So the USB device structure isn't the right thing to look at, but us_data
which keeps the GUID probably is.  It's got a pointer to the Scsi_Host,
which has its PCI information.

Thanks,
Matt

--
Matt Domsch
Sr. Software Engineer, Lead Engineer, Architect
Dell Linux Solutions www.dell.com/linux
Linux on Dell mailing lists @ http://lists.us.dell.com


^ permalink raw reply	[flat|nested] 13+ messages in thread
* RE: devicefs requests
@ 2002-09-26  3:48 Matt_Domsch
  2002-09-26  4:14 ` Greg KH
  0 siblings, 1 reply; 13+ messages in thread
From: Matt_Domsch @ 2002-09-26  3:48 UTC (permalink / raw)
  To: greg; +Cc: mochel, linux-kernel

> Um, what 64-bit unique id?  USB devices do not have such a thing.

The EDD spec (http://www.t13.org/docs2002/d1572r0.pdf - T13 committee
project 1572D BIOS Enhanced Disk Drive Services - 3) says:
USB identifier:  64-bit Serial Number as defined in the USB Mass Storage
specifications

I assume that they mean the USB Mass Storage spec v1.0
(http://www.usb.org/developers/data/devclass/usbmassbulk_10.pdf) section
4.1.1 - Serial Number, which is 12-16 bytes long.  drivers/usb/storage/usb.c
turns that into a 16-byte GUID in storage_probe().  I hadn't gotten so far
as to see that these two specs don't agree for USB - I'd been looking at the
IDE and SCSI descriptions so far.  It wouldn't be the first time the EDD
spec needed editing, and given that few (if any) BIOSs yet implement it
apart from SCSI, is reason for the confusion.

I don't think Dell has a T13 committee representative right now, but I'll
see if we have a process for getting this cleared up through official
channels.  As I'm not a USB expert, would you care to comment on the right
way to handle this (i.e. instead of a 64-bit serial number, use the 16-byte
GUID)?

Thanks,
Matt

--
Matt Domsch
Sr. Software Engineer, Lead Engineer, Architect
Dell Linux Solutions www.dell.com/linux
Linux on Dell mailing lists @ http://lists.us.dell.com
#1 US Linux Server provider for 2001 and Q1/2002! (IDC May 2002)


^ permalink raw reply	[flat|nested] 13+ messages in thread
* RE: devicefs requests
@ 2002-09-25 22:11 Matt_Domsch
  0 siblings, 0 replies; 13+ messages in thread
From: Matt_Domsch @ 2002-09-25 22:11 UTC (permalink / raw)
  To: greg; +Cc: mochel, linux-kernel

> Fair enough.  I actually only need the 64-bit unique ID that 
> the USB device provides, and its parent PCI device.  

Oh, and of course being able to walk the list of existing devices on that
bus (similar to bus_for_each_dev() now, with a callback mechanism that
allows comparison of one device (BIOSs idea of a device) with what the
device thinks of itself - to allow matching.

-Matt

--
Matt Domsch
Sr. Software Engineer, Lead Engineer, Architect
Dell Linux Solutions www.dell.com/linux
Linux on Dell mailing lists @ http://lists.us.dell.com


^ permalink raw reply	[flat|nested] 13+ messages in thread
* RE: devicefs requests
@ 2002-09-25 22:03 Matt_Domsch
  2002-09-25 22:46 ` Greg KH
  2002-10-01  1:39 ` Patrick Mochel
  0 siblings, 2 replies; 13+ messages in thread
From: Matt_Domsch @ 2002-09-25 22:03 UTC (permalink / raw)
  To: greg; +Cc: mochel, linux-kernel

> But what do you do with the usb_bus_type?  Why would your code use
> anything that is private to the driver core?

Fair enough.  I actually only need the 64-bit unique ID that the USB device
provides, and its parent PCI device.  EDD provides this info as x86 BIOS
sees it, so my code compares the two, and will make a symlink between the
two.  This lets the OS know which device BIOS thinks it is (i.e. to know
what disk you're booting from).

True, I don't (today) see a unique ID in struct usb_device.  Hopefully
that's something that can be added in the future.  Functions which expose
this info separate from exporting the bus type would be great.

SCSI has a different set of things that EDD needs exported (channel, id,
lun).  IDE still different (channel, number (master/slave)), plus parent PCI
device.

> Oh yeah, it's "driverfs" not "devicefs"  :)

Yes, my bad.

Thanks,
Matt

--
Matt Domsch
Sr. Software Engineer, Lead Engineer, Architect
Dell Linux Solutions www.dell.com/linux
Linux on Dell mailing lists @ http://lists.us.dell.com


^ permalink raw reply	[flat|nested] 13+ messages in thread
* devicefs requests
@ 2002-09-25 19:28 Matt_Domsch
  2002-09-25 21:33 ` Greg KH
                   ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: Matt_Domsch @ 2002-09-25 19:28 UTC (permalink / raw)
  To: mochel; +Cc: linux-kernel

Pat,

1)  As new drivers pick up the model, check that all xxx_bus_type objects
get EXPORT_SYMBOLd and included in a include/xxxx header somewhere - My BIOS
EDD code walks the list of bus types looking for attached devices to compare
against (pci, ide, scsi, usb, ...).
ide_bus_type is in include/linux/ide.h but isn't EXPORT_SYMBOL;
usb_bus_type is in include/linux/usb.h but isn't EXPORT_SYMBOL;

Alternately, keep the list of registered bus types accessible via a
list_for_each type macro.  I like the exported symbols myself, it lets me
do:

struct edd_known_bus_types_s {
	struct bus_type *bus;
	const char *edd_type;
	int (*match)(struct device *edd_dev, struct device *dev);
};

static const struct edd_known_bus_types_s edd_known_bus_types[] = {
	{bus:&scsi_driverfs_bus_type, edd_type: "SCSI", match:
edd_match_scsidev},
//	{bus:&ide_bus_type,           edd_type: "ATA",  match: NULL},
//	{bus:&usb_bus_type,           edd_type: "USB",  match: NULL},
	{bus:NULL,                    edd_type: NULL,   match: NULL},
};

so I can supply my own match functions which match one type of device (e.g.
EDD's idea of a SCSI device) to that of the standard device.  I could
accomplish the same using well-known names for bus_type I suppose, and doing
a list_for_each until I find it.  Just a different thing getting exported, a
well-known name and a lookup method rather than the symbol itself.


2) bus_for_each_dev() is really restrictive right now due to all the locking
mechanisms in place.  In my code I'd like to, given a struct device *, walk
a list of devices on a given bus and compare each device with the given
device, returning a match, or not.  As it stands, bus_for_each_dev returns
either success (the callback worked for each device on the list), or failure
(the callback failed for some device on the list), but I don't see a
mechanism to return which device failed without excessive abuse of the
void*.  For now I've made a private copy of bus_for_each_dev which I've
mucked with the return the properly matching device, and wonder if this
couldn't be made more generic somehow.

Thoughts?

Thanks,
Matt

--
Matt Domsch
Sr. Software Engineer, Lead Engineer, Architect
Dell Linux Solutions www.dell.com/linux
Linux on Dell mailing lists @ http://lists.us.dell.com


^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2002-10-01  1:32 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-09-26 16:13 devicefs requests Matt_Domsch
2002-09-27  4:41 ` Greg KH
  -- strict thread matches above, loose matches on Subject: below --
2002-09-26  3:48 Matt_Domsch
2002-09-26  4:14 ` Greg KH
2002-09-26 14:41   ` Randy.Dunlap
2002-09-25 22:11 Matt_Domsch
2002-09-25 22:03 Matt_Domsch
2002-09-25 22:46 ` Greg KH
2002-10-01  1:39 ` Patrick Mochel
2002-09-25 19:28 Matt_Domsch
2002-09-25 21:33 ` Greg KH
2002-09-25 21:33 ` Greg KH
2002-10-01  1:32 ` Patrick Mochel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).