Re: [PATCH 0/5] sg_ring for scsi
From: Rusty Russell <[EMAIL PROTECTED]> Date: Thu, 20 Dec 2007 18:53:48 +1100 > Manipulating the magic chains is horrible; it looks simple to the > places which simply want to iterate through it, but it's awful for > code which wants to create them. I'm not saying complexity is inherent in this stuff, but assuming that it is the complexity should live as far away from the minions (the iterators in this case). Therefore, the creators is the right spot for the hard stuff. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] x86: Voluntary leave_mm before entering ACPI C3
On Wed, 19 Dec 2007 11:48:14 -0800 "H. Peter Anvin" <[EMAIL PROTECTED]> wrote: > > I think C3 guarantees that the cache contents stay intact, and thus > it might make sense in some technology to preserve the TLB as well > (being a kind of cache.) that sounds nice. It's fiction though ;-) The thing to realize is that linux only sees "ACPI C3"; the BIOS maps that C3 to.. well any of the C states the processor in the system has. What you're saying is afaik correct for the *hardware* C3, not for the "C3" that Linux sees.. -- If you want to reach me at my work email, use [EMAIL PROTECTED] For development, discussion and tips for power savings, visit http://www.lesswatts.org -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC] kobject/kset/ktype documentation and example code updated
On Dec 20, 2007 8:30 AM, Greg KH <[EMAIL PROTECTED]> wrote: > Thanks to everyone for your last round of review comments and changes to > the kobject documentation. > > I now have over 130 patches reworking the kset/ktype and kobject apis in > the kernel tree, and here is the updated documentation and example code > that shows how things work now. > > Things different from the last time around are the kobject_add() and > kobject_init() functions now take a bunch of required parameters, and > the kobject cleanup code is much more forgiving. > > I want to drop kobject_unregister() but as this patch series is so big > already, I think it's time to let it bake in -mm and push into 2.6.25 > before attempting it. [--snip--] Hi, greg How about add a kobject_remove function and temporarily keep the kobject_unregister as below until the 2.6.25: kobject_unregister(...) { ... kobject_remove(); kobject_uevent(); ... } -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 0/5] sg_ring for scsi
On Thursday 20 December 2007 18:07:41 FUJITA Tomonori wrote: > On Thu, 20 Dec 2007 16:45:18 +1100 > > Rusty Russell <[EMAIL PROTECTED]> wrote: > > OK, some fixes since last time, as I wade through more SCSI drivers. > > Some drivers use "use_sg" as a flag to know whether the request_buffer is > > a scatterlist: I don't need the counter, but I still need the flag, so I > > fixed that in a more intuitive way (an explicit ->sg pointer in the cmd). > > use_sg and the request_buffer will be removed shortly. > > http://marc.info/?l=linux-scsi=119754650614813=2 Thanks! Is there a git tree somewhere with these changes? > I think that we tried the similar idea before, scsi_sgtable, but we > seem to settle in the current simple approach. Yes, a scsi-specific solution is a bad idea: other people use sg. Manipulating the magic chains is horrible; it looks simple to the places which simply want to iterate through it, but it's awful for code which wants to create them. Cheers, Rusty. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [patch 1/2] [RFC] Simple tamper-proof device filesystem.
Oren Laadan wrote: > > Serge E. Hallyn wrote: >> Quoting Pavel Emelyanov ([EMAIL PROTECTED]): >>> Oren Laadan wrote: Serge E. Hallyn wrote: > Quoting Oren Laadan ([EMAIL PROTECTED]): >> I hate to bring this again, but what if the admin in the container >> mounts an external file system (eg. nfs, usb, loop mount from a file, >> or via fuse), and that file system already has a device that we would >> like to ban inside that container ? > Miklos' user mount patches enforced that if !capable(CAP_MKNOD), > then mnt->mnt_flags |= MNT_NODEV. So that's no problem. Yes, that works to disallow all device files from a mounted file system. But it's a black and white thing: either they are all banned or allowed; you can't have some devices allowed and others not, depending on type A scenario where this may be useful is, for instance, if we some apps in the container to execute withing a pre-made chroot (sub)tree within that container. > But that's been pulled out of -mm! ? Crap. > >> Since anyway we will have to keep a white- (or black-) list of devices >> that are permitted in a container, and that list may change even change >> per container -- why not enforce the access control at the VFS layer ? >> It's safer in the long run. > By that you mean more along the lines of Pavel's patch than my whitelist > LSM, or you actually mean Tetsuo's filesystem (i assume you don't mean > that > by 'vfs layer' :), or something different entirely? :) By 'vfs' I mean at open() time, and not at mount(), or mknod() time. Either yours or Pavel's; I tend to prefer not to use LSM as it may collide with future security modules. >>> Oren, AFAIS you've seen my patches for device access controller, right? > > If you mean this one: > http://openvz.org/pipermail/devel/2007-September/007647.html > then ack :) Great! Thanks. >>> Maybe we can revisit the issue then and try to come to agreement on what >>> kind of model and implementation we all want? >> That would be great, Pavel. I do prefer your solution over my LSM, so >> if we can get an elegant block device control right in the vfs code that >> would be my preference. > > I concur. > > So it seems to me that we are all in favor of the model where open() > of a device will consult a black/white-list. Also, we are all in favor > of a non-LSM implementation, Pavel's code being a good example. Thank you, Oren and Serge! I will revisit this issue then, but I have a vacation the next week and, after this, we have a New Year and Christmas holidays in Russia. So I will be able to go on with it only after the 7th January :( Hope this is OK for you. Besides, Andrew told that he would pay little attention to new features till the 2.6.24 release, so I'm afraid we won't have this even in -mm in the nearest months :( Thanks, Pavel > Oren. > >> The only thing that makes me keep wanting to go back to an LSM is the >> fact that the code defining the whitelist seems out of place in the vfs. >> But I guess that's actually separated into a modular cgroup, with the >> actual enforcement built in at the vfs. So that's really the best >> solution. >> >> -serge > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 2/5] dma_map_sg_ring() helper
From: FUJITA Tomonori <[EMAIL PROTECTED]> Date: Thu, 20 Dec 2007 16:06:31 +0900 > On Thu, 20 Dec 2007 16:49:30 +1100 > Rusty Russell <[EMAIL PROTECTED]> wrote: > > > +/** > > + * dma_map_sg_ring - Map an entire sg ring > > + * @dev: Device to free noncoherent memory for > > + * @sg: The sg_ring > > + * @direction: DMA_TO_DEVICE, DMA_FROM_DEVICE or DMA_BIDIRECTIONAL. > > + * > > + * This returns -ENOMEM if mapping fails. It's not clear that telling you > > + * it failed is useful though. > > + */ > > +int dma_map_sg_ring(struct device *dev, struct sg_ring *sg, > > +enum dma_data_direction direction) > > +{ > > + struct sg_ring *i; > > + unsigned int num; > > + > > + for (i = sg; i; i = sg_ring_next(i, sg)) { > > + BUG_ON(i->num > i->max); > > + num = dma_map_sg(dev, i->sg, i->num, direction); > > + if (num == 0 && i->num != 0) > > + goto unmap; > > + } > > + return 0; > > I don't think that this works for IOMMUs that could merge sg entries. Right, it won't work at all. The caller has to be told how many DMA entries it really did use to compose the mapping, and there has to be a way to properly iterate over them. The assumption that the IOMMU will map the SG entries 1-to-1 is invalid. The IOMMU code can and will map thousands of pages all to one linear DMA address+length pair of all the segments start and end on page boundaries, since it can virtually remap those pages however it chooses. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC] kobject/kset/ktype documentation and example code updated
On Wed, 2007-12-19 at 23:26 -0500, Alan Stern wrote: > On Wed, 19 Dec 2007, Greg KH wrote: > > associated with a kobject, then the parent for the kobject can be set to > > NULL in the call to kobject_add() and then the kobject will be placed under > > the kset itself. > > "and then the kobject's parent will be set to the kset itself." > > Kay, in my version of kobject_add() it says: > > if (kobj->kset) { > kobj->kset = kset_get(kobj->kset); > > if (!parent) { > parent = kobject_get(>kset->kobj); > /* >* If the kset is our parent, get a second >* reference, we drop both the kset and the >* parent ref on cleanup >*/ > kobject_get(parent); > } > > That last call to kobject_get(parent) doesn't make sense. The code has > already taken two references to the kset: one in the assignment of > kobj->kset and the other in the assignment of parent. The final > kobject_get() then acquires a third reference, which will never be > dropped. Yeah, that's wrong, and caused by two patches trying to solve the same problem. We had users assigning the kset before kobject_init() and users doing that after it. We moved the kset referencing from kobiect_init to kobject_add, which introduced the third reference, while we already added the second one to fix the issues. We could drop one of the patches in the series, but this is all already gone with the latest changes in Greg's tree. Thanks, Kay -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC, PATCH] sdio: move temporary buffer
On Wednesday 19 December 2007, Pierre Ossman wrote: > On Wed, 19 Dec 2007 11:55:25 +0100 ... > This is still voodoo to me, so I'll have to take your word for it. :) And almost voodoo to me... this is why I hope an ack from a DMA mentor! Marc -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [patch 17/20] non-reclaimable mlocked pages
On Wed, 19 Dec 2007, Nick Piggin wrote: > These mlocked pages don't need to be on a non-reclaimable list, > because we can find them again via the ptes when they become > unlocked, and there is no point background scanning them, because > they're always going to be locked while they're mlocked. But there is something to be said for having a consistent scheme. Here we already introduce address space flags for one kind of unreclaimability. Isnt it possible to come up with a way to categorize pages that works (mostly) the same way for all types of pages with reclaim issues? -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [patch 03/20] move isolate_lru_page() to vmscan.c
Reviewed-by: Christoph Lameter <[EMAIL PROTECTED]> -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 0/5] sg_ring for scsi
On Thu, 20 Dec 2007 16:45:18 +1100 Rusty Russell <[EMAIL PROTECTED]> wrote: > OK, some fixes since last time, as I wade through more SCSI drivers. Some > drivers use "use_sg" as a flag to know whether the request_buffer is a > scatterlist: I don't need the counter, but I still need the flag, so I fixed > that in a more intuitive way (an explicit ->sg pointer in the cmd). use_sg and the request_buffer will be removed shortly. http://marc.info/?l=linux-scsi=119754650614813=2 I think that we tried the similar idea before, scsi_sgtable, but we seem to settle in the current simple approach. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [patch 01/20] convert anon_vma list lock a read/write lock
Reviewed-by: Christoph Lameter <[EMAIL PROTECTED]> Note that this is a nice improvement also to page migration. Another solution may be to use a single linked list and RCU. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 2/5] dma_map_sg_ring() helper
On Thu, 20 Dec 2007 16:49:30 +1100 Rusty Russell <[EMAIL PROTECTED]> wrote: > Obvious counterpart to dma_map_sg. Note that this is arch-independent > code; sg_rings are backwards compatible with simple sg arrays. > > Signed-off-by: Rusty Russell <[EMAIL PROTECTED]> > --- > drivers/base/dma-mapping.c | 13 + > include/linux/dma-mapping.h |4 > 2 files changed, 17 insertions(+), 0 deletions(-) > > diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c > --- a/drivers/base/dma-mapping.c > +++ b/drivers/base/dma-mapping.c > @@ -8,6 +8,7 @@ > */ > > #include > +#include > > /* > * Managed DMA API > @@ -162,6 +163,59 @@ void dmam_free_noncoherent(struct device > } > EXPORT_SYMBOL(dmam_free_noncoherent); > > +/** > + * dma_map_sg_ring - Map an entire sg ring > + * @dev: Device to free noncoherent memory for > + * @sg: The sg_ring > + * @direction: DMA_TO_DEVICE, DMA_FROM_DEVICE or DMA_BIDIRECTIONAL. > + * > + * This returns -ENOMEM if mapping fails. It's not clear that telling you > + * it failed is useful though. > + */ > +int dma_map_sg_ring(struct device *dev, struct sg_ring *sg, > + enum dma_data_direction direction) > +{ > + struct sg_ring *i; > + unsigned int num; > + > + for (i = sg; i; i = sg_ring_next(i, sg)) { > + BUG_ON(i->num > i->max); > + num = dma_map_sg(dev, i->sg, i->num, direction); > + if (num == 0 && i->num != 0) > + goto unmap; > + } > + return 0; I don't think that this works for IOMMUs that could merge sg entries. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [patch 02/20] make the inode i_mmap_lock a reader/writer lock
> The only reason the x86 ticket locks have the 256 CPu limit is that > if they go any bigger, we can't use the partial registers so would > have to have a few more instructions. x86_64 is going up to 4k or 16k cpus soon for our new hardware. > A 32 bit spinlock would allow 64K cpus (ticket lock has 2 counters, > each would be 16 bits). And it would actually shrink the spinlock in > the case of preempt kernels too (because it would no longer have the > lockbreak field). > > And yes, I'll go out on a limb and say that 64k CPUs ought to be > enough for anyone ;) I think those things need a timeframe applied to it. Thats likely going to be true for the next 3 years (optimistic assessment ;-)). Could you go to 32bit spinlock by default? How about NUMA awareness for the spinlocks? Larger backoff periods for off node lock contentions please. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 1/3] pci: Add pci_enable_device_{io,mem} intefaces
On Thu, Dec 20, 2007 at 03:28:08PM +1100, Benjamin Herrenschmidt wrote: > Signed-off-by: Benjamin Herrenschmidt <[EMAIL PROTECTED]> Acked-by: Ivan Kokshaysky <[EMAIL PROTECTED]> Ivan. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [RFC] kobject/kset/ktype documentation and example code updated
On Wed, 19 Dec 2007 16:30:31 -0800 Greg KH wrote: > Everything you never wanted to know about kobjects, ksets, and ktypes > > Greg Kroah-Hartman <[EMAIL PROTECTED]> > > Based on an original article by Jon Corbet for lwn.net written October 1, > 2003 and located at http://lwn.net/Articles/51437/ > > Last updated December 19, 2007 > > ... > - A ktype is the type of object that embeds a kobject. Every structure >that embeds a kobject needs a corresponding ktype. The ktype controls >what happens when a kobject is no longer referenced and the kobject's >default representation in sysfs. I can't quite parse the last sentence above. Is it: The ktype controls (a) what happens ... and (b) the kobject's default representation in sysfs. ? > Embedding kobjects > > So, for example, the UIO code has a structure that defines the memory > region associated with a uio device: > > struct uio_mem { > struct kobject kobj; > unsigned long addr; > unsigned long size; > int memtype; > void __iomem *internal_addr; > }; > > If you have a struct uio_mem structure, finding its embedded kobject is > just a matter of using the kobj structure. Code that works with kobjects > will often have the opposite problem, however: given a struct kobject > pointer, what is the pointer to the containing structure? You must avoid > tricks (such as assuming that the kobject is at the beginning of the > structure) and, instead, use the container_of() macro, found in > : > > container_of(pointer, type, member) > > where pointer is the pointer to the embedded kobject, type is the type of > the containing structure, and member is the name of the structure field to > which pointer points. The return value from container_of() is a pointer to > the given type. So, for example, a pointer to a struct kobject embedded This is (still) confusing to me. Is it: a pointer "kp" to a ... or is struct uio_mem the "kp"? > within a struct uio_mem called "kp" could be converted to a pointer to the > containing structure with: > > struct uio_mem *u_mem = container_of(kp, struct uio_mem, kobj); > > Programmers will often define a simple macro for "back-casting" kobject Drop the "will". > pointers to the containing type. > > > Initialization of kobjects > > > int kobject_add(struct kobject *kobj, struct kobject *parent, const char > *fmt, ...); > > This sets up the parent of the kobject, and the name for the kobject Drop the comma. > properly. If the kobject is to be associated with a specific kset, that > assignment must be done before calling kobject_add(). If a kset is > associated with a kobject, then the parent for the kobject can be set to > NULL in the call to kobject_add() and then the kobject will be placed under > the kset itself. > > As the name of the kobject is set when it is added to the kernel, the name > of the kobject should never be manipulated directly. If you must change > the name of the kobject, call kobject_rename(): > > int kobject_rename(struct kobject *kobj, const char *new_name); > > There is a function called kobject_set_name() but that is legacy cruft and > is being removed. If your code needs to call this function, it is > incorrect and needs to be fixed. Is kobject_set_name() marked as __deprecated ? > Uevents > > After a kobject has been registered with the kobject core, it needs to be > announced to the world that it has been created. This can be done with > call to kobject_uevent(): a call ... > > int kobject_uevent(struct kobject *kobj, enum kobject_action action); > > Use the KOBJ_ADD action for when the kobject is first added to the kernel. > This should be done only after any attributes or children of the kobject > have been initialized properly, as userspace will instantly start to look s/will/may/ > for them when this call happens. > > When the kobject is removed from the kernel (details on how to do that is are > below), the uevent for KOBJ_REMOVE will be automatically created by the > kobject core, so the caller does not have to worry about doing that by > hand. > > > Reference counts > ... > > Because kobjects are dynamic, they must not be declared statically or on > the stack, but instead, always allocated from the heap. Future versions of The kernel has heapspace? > the kernel will contain a run-time check for kobjects that are created > statically and will warn the developer of this improper usage. > > If all that you are wanting to use a kobject for is to provide a reference If all that you want to use a kobject for is to provide a reference > counter for your structure, please use the struct kref instead, a kobject > would be overkill. For more information on how to use struct kref, please > see the file, Documentation/kref.txt in the Linux kernel source tree. Drop
Re: [PATCH] [RFC] Xilinx SystemACE: Add media hotplug support
On 12/19/07, Grant Likely <[EMAIL PROTECTED]> wrote: > From: Grant Likely <[EMAIL PROTECTED]> > > Please review and comment. This patch works in my setup, but I haven't > tested exhaustively yet. I also need to fixup the documentation to > reflect new states before I request this patch to be merged. > > Question for the block layer experts: I'm using add_disk()/del_gendisk() > functions to inform the kernel of media insertion and removal events. Is > this the best way to do this? I looked at the .media_changed and > .revalidate_disk hooks, but it doesn't seem like they offer the driver > any way to notify the kernel of media removal (as opposed to the kernel > asking the driver) Heh, actually I *know* I'm doing the wrong thing; but I'm hoping I've got better chances of getting steered in the right direction if I start by throwing code out there. Currently this patch handles insertion/removal just fine if nothing is mounted, but gets stuck if the disk is in use. How do I get the kernel to cancel all pending requests when deregistering the device? Thanks, g. -- Grant Likely, B.Sc., P.Eng. Secret Lab Technologies Ltd. [EMAIL PROTECTED] (403) 399-0195 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] [RFC] Xilinx SystemACE: Add media hotplug support
From: Grant Likely <[EMAIL PROTECTED]> Please review and comment. This patch works in my setup, but I haven't tested exhaustively yet. I also need to fixup the documentation to reflect new states before I request this patch to be merged. Question for the block layer experts: I'm using add_disk()/del_gendisk() functions to inform the kernel of media insertion and removal events. Is this the best way to do this? I looked at the .media_changed and .revalidate_disk hooks, but it doesn't seem like they offer the driver any way to notify the kernel of media removal (as opposed to the kernel asking the driver) Cheers, g. --- drivers/block/xsysace.c | 265 ++- 1 files changed, 189 insertions(+), 76 deletions(-) diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c index 0cdc868..9b3df96 100644 --- a/drivers/block/xsysace.c +++ b/drivers/block/xsysace.c @@ -53,7 +53,7 @@ *The request method in particular schedules the tasklet when a new *request has been indicated by the block layer. Once started, the *FSM proceeds as far as it can processing the request until it - *needs on a hardware event. At this point, it must yield execution. + *needs a hardware event. At this point, it must yield execution. * *A state has two options when yielding execution: *1. ace_fsm_yield() @@ -71,7 +71,8 @@ *Additionally, the driver maintains a kernel timer which can process *the FSM. If the FSM gets stalled, typically due to a missed *interrupt, then the kernel timer will expire and the driver can - *continue where it left off. + *continue where it left off. The stall timer is also used to watch + *for media removal/insertion events. * * To Do: *- Add FPGA configuration control interface. @@ -90,6 +91,7 @@ #include #include #include +#include #include #if defined(CONFIG_OF) #include @@ -170,17 +172,18 @@ struct ace_reg_ops; struct ace_device { /* driver state data */ int id; - int media_change; int users; struct list_head list; /* finite state machine data */ struct tasklet_struct fsm_tasklet; + struct work_struct fsm_worker; uint fsm_task; /* Current activity (ACE_TASK_*) */ uint fsm_state; /* Current state (ACE_FSM_STATE_*) */ uint fsm_continue_flag; /* cleared to exit FSM mainloop */ uint fsm_iter_num; struct timer_list stall_timer; + int stall_count; /* Transfer state/result, use for both id and block request */ struct request *req;/* request being processed */ @@ -189,7 +192,6 @@ struct ace_device { int data_result;/* Result of transfer; 0 := success */ int id_req_count; /* count of id requests */ - int id_result; struct completion id_completion;/* used when id req finishes */ int in_irq; @@ -212,6 +214,7 @@ struct ace_device { }; static int ace_major; +struct workqueue_struct *ace_workqueue; /* - * Low level register access @@ -429,21 +432,24 @@ void ace_fix_driveid(struct hd_driveid *id) #define ACE_TASK_IDENTIFY 1 #define ACE_TASK_READ 2 #define ACE_TASK_WRITE 3 -#define ACE_FSM_NUM_TASKS 4 +#define ACE_NUM_TASKS 4 /* FSM state definitions */ -#define ACE_FSM_STATE_IDLE 0 -#define ACE_FSM_STATE_REQ_LOCK 1 -#define ACE_FSM_STATE_WAIT_LOCK 2 -#define ACE_FSM_STATE_WAIT_CFREADY 3 -#define ACE_FSM_STATE_IDENTIFY_PREPARE 4 -#define ACE_FSM_STATE_IDENTIFY_TRANSFER 5 -#define ACE_FSM_STATE_IDENTIFY_COMPLETE 6 -#define ACE_FSM_STATE_REQ_PREPARE7 -#define ACE_FSM_STATE_REQ_TRANSFER 8 -#define ACE_FSM_STATE_REQ_COMPLETE 9 -#define ACE_FSM_STATE_ERROR 10 -#define ACE_FSM_NUM_STATES 11 +#define ACE_FSM_STATE_NO_MEDIA 0 +#define ACE_FSM_STATE_KICKSTART 1 +#define ACE_FSM_STATE_IDLE 2 +#define ACE_FSM_STATE_REQ_LOCK 3 +#define ACE_FSM_STATE_WAIT_LOCK 4 +#define ACE_FSM_STATE_WAIT_CFREADY 5 +#define ACE_FSM_STATE_IDENTIFY_PREPARE 6 +#define ACE_FSM_STATE_IDENTIFY_TRANSFER 7 +#define ACE_FSM_STATE_IDENTIFY_COMPLETE 8 +#define ACE_FSM_STATE_REQ_PREPARE9 +#define ACE_FSM_STATE_REQ_TRANSFER 10 +#define ACE_FSM_STATE_REQ_COMPLETE 11 +#define ACE_FSM_STATE_INVALIDATE_MEDIA 12 +#define ACE_FSM_STATE_MEDIA_DISABLED13 +#define ACE_FSM_NUM_STATES 14 /* Set flag to exit FSM loop and reschedule tasklet */ static inline void ace_fsm_yield(struct ace_device *ace) @@ -490,18 +496,53 @@ static void ace_fsm_dostate(struct ace_device *ace) ace->fsm_state, ace->id_req_count); #endif + /* Before doing anything; check the CF detect bit. If the card +* is not present; then there
Re: OOPS: 2.6.24-rc5-mm1 -- EIP is at r_show+0x2a/0x70 -- (triggered by "cat /proc/iomem")
On Thu, 20 Dec 2007 00:35:51 -0500 Miles Lane <[EMAIL PROTECTED]> wrote: > Added Ingo and Russell to the TO list, since they seem to potentially be > the right people to look into this. > .config attached in order to not trip spam filters. > > Miles Lane wrote: > > Okay. The command that directly triggers this is: cat /proc/iomem > > > > Here is the stack trace without the line-wrapping (sorry!): > > > > [ 251.602965] wlan0_rename: RX non-WEP frame, but expected encryption > > [ 252.868386] BUG: unable to handle kernel NULL pointer dereference > > at virtual address 0018 > > [ 252.868393] printing ip: c012d527 *pde = > > [ 252.868399] Oops: [#1] SMP > > [ 252.868403] last sysfs file: > > /sys/devices/pci:00/:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda3/stat > > > > > > [ 252.868407] Modules linked in: aes_i586 aes_generic i915 drm rfcomm > > l2cap bluetooth acpi_cpufreq cpufreq_stats cpufreq_conservative sbs > > sbshc dm_crypt sbp2 parport_pc lp parport arc4 ecb crypto_blkcipher > > cryptomgr crypto_algapi snd_hda_intel snd_pcm_oss snd_mixer_oss pcmcia > > snd_pcm iTCO_wdt iTCO_vendor_support snd_seq_dummy watchdog_core > > watchdog_dev snd_seq_oss snd_seq_midi tifm_7xx1 snd_rawmidi iwl3945 > > snd_seq_midi_event rng_core tifm_core mac80211 snd_seq snd_timer > > snd_seq_device cfg80211 sky2 battery yenta_socket rsrc_nonstatic > > pcmcia_core ac snd soundcore snd_page_alloc button shpchp pci_hotplug > > sr_mod cdrom pata_acpi piix ide_core firewire_ohci firewire_core > > crc_itu_t thermal processor fan > > [ 252.868469] > > [ 252.868472] Pid: 7088, comm: head Not tainted (2.6.24-rc5-mm1 #9) > > [ 252.868476] EIP: 0060:[] EFLAGS: 00010297 CPU: 0 > > [ 252.868481] EIP is at r_show+0x2a/0x70 > > [ 252.868483] EAX: EBX: 0001 ECX: c07e3224 EDX: c04bb034 > > [ 252.868486] ESI: 0008 EDI: ed1f52c0 EBP: f5320f10 ESP: f5320f04 > > [ 252.868489] DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068 > > [ 252.868493] Process head (pid: 7088, ti=f532 task=f532e000 > > task.ti=f532) > > [ 252.868495] Stack: c03a6cac ed1f52c0 c07e3224 f5320f50 c0199a7e > > 2000 bf930807 e1007800 > > [ 252.868504]ed1f52e0 01d3 000e > > 000d > > [ 252.868512]fffb f7d39370 c01998e4 f5320f74 c01af4f5 > > f5320f9c 2000 bf930807 > > [ 252.868521] Call Trace: > > [ 252.868523] [] show_trace_log_lvl+0x12/0x25 > > [ 252.868529] [] show_stack_log_lvl+0x8a/0x95 > > [ 252.868534] [] show_registers+0x8c/0x154 > > [ 252.868538] [] die+0x10e/0x1d2 > > [ 252.868542] [] do_page_fault+0x52b/0x600 > > [ 252.868547] [] error_code+0x72/0x78 > > [ 252.868552] [] seq_read+0x19a/0x26c > > [ 252.868557] [] proc_reg_read+0x60/0x74 > > [ 252.868562] [] vfs_read+0xa2/0x11e > > [ 252.868567] [] sys_read+0x3b/0x60 > > [ 252.868571] [] sysenter_past_esp+0x6b/0xc1 > > [ 252.868575] === > > [ 252.868577] Code: c3 55 89 d1 89 e5 57 89 c7 56 53 8b 50 64 83 7a > > 0c 00 77 0e 81 7a 08 ff ff 00 00 be 04 00 00 00 76 05 be 08 00 00 00 > > 89 c8 31 db <8b> 40 18 39 d0 74 06 43 83 fb 05 75 f3 8b 41 10 ba 2f 1b > > 45 c0 > > [ 252.868623] EIP: [] r_show+0x2a/0x70 SS:ESP 0068:f5320f04 > > > > I would be suspecting iget-stop-procfs-from-using-iget-and-read_inode.patch. Here's a (tested) revert of various bits. Can you please try it against 2.6.24-rc5-mm1? Thanks. Documentation/filesystems/Locking |3 + Documentation/filesystems/porting | 12 ++--- Documentation/filesystems/vfs.txt | 17 ++- fs/inode.c|4 + fs/proc/inode.c | 60 ++-- include/linux/fs.h| 14 ++ 6 files changed, 73 insertions(+), 37 deletions(-) diff -puN fs/proc/inode.c~revert-iget-stop-procfs-from-using-iget-and-read_inode-checkpatch-fixes fs/proc/inode.c --- a/fs/proc/inode.c~revert-iget-stop-procfs-from-using-iget-and-read_inode-checkpatch-fixes +++ a/fs/proc/inode.c @@ -73,6 +73,11 @@ static void proc_delete_inode(struct ino struct vfsmount *proc_mnt; +static void proc_read_inode(struct inode * inode) +{ + inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; +} + static struct kmem_cache * proc_inode_cachep; static struct inode *proc_alloc_inode(struct super_block *sb) @@ -123,6 +128,7 @@ static int proc_remount(struct super_blo static const struct super_operations proc_sops = { .alloc_inode= proc_alloc_inode, .destroy_inode = proc_destroy_inode, + .read_inode = proc_read_inode, .drop_inode = generic_delete_inode, .delete_inode = proc_delete_inode, .statfs = simple_statfs, @@ -395,41 +401,39 @@ struct inode *proc_get_inode(struct supe if (de != NULL && !try_module_get(de->owner)) goto out_mod; - inode = iget_locked(sb, ino); + inode = iget(sb, ino);
Re: [PATCH 4/5] Convert PowerPC MPC i2c to of_platform_driver from platform_driver
On Thursday 20 December 2007, David Gibson wrote: > On Wed, Dec 19, 2007 at 11:41:44PM -0500, Jon Smirl wrote: > > Convert MPC i2c driver from being a platform_driver to an open > > firmware version. Error returns were improved. Routine names were > > changed from fsl_ to mpc_ to make them match the file name. > > In discussions BenH and I have had, we've actually concluded that > moving this from platform drivers to of_platform drives is not > actually a good idea. > > In fact we're planning to move away from of_platform devices and > drivers and instead develop a framework for instantiating platform > devices or i2c devices or whatever devices from the device tree nodes. Now that is interesting news. I like this idea. But what should be done to support the still missing devices in the 4xx arch/powerpc tree, like I2C, NAND etc.? Should we wait with those driver till this framework is available? Thanks. Cheers, Stefan -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 4/5] Convert PowerPC MPC i2c to of_platform_driver from platform_driver
On Thu, Dec 20, 2007 at 04:16:18PM +1100, David Gibson wrote: > On Wed, Dec 19, 2007 at 11:41:44PM -0500, Jon Smirl wrote: > > Convert MPC i2c driver from being a platform_driver to an open > > firmware version. Error returns were improved. Routine names were > > changed from fsl_ to mpc_ to make them match the file name. > > In discussions BenH and I have had, we've actually concluded that > moving this from platform drivers to of_platform drives is not > actually a good idea. > > In fact we're planning to move away from of_platform devices and > drivers and instead develop a framework for instantiating platform > devices or i2c devices or whatever devices from the device tree nodes. There's been talk about that for a long time. Whenever that framework is done, all the other drivers that have been converted (or written) must/can be converted back as well. Meanwhile, this should go in so those of us who can make use of the other improvements the series brings can make use of them. Thanks, Olof -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 5/5] sg_ring: Convert scsi_debug
Douglas Gilbert pointed out that converting scsi_debug would be a good demonstration of the conversion required for other SCSI devices. Details of the changes: 1) ->use_sg is replaced by ->sg, which if non-NULL, contains the sg_ring. 2) ->request_buffer can be NULL (it's only relevent if ->sg isn't set) 3) sg_ring_for_each is no longer required, just iterate directly over ->sg. 4) The iterator updates a struct sg_ring (sg) and an index (k), so previous references to sg become >sg[k] (the k'th element within the sg_ring sg). Signed-off-by: Rusty Russell <[EMAIL PROTECTED]> diff -r c5fe2cab1d48 drivers/scsi/scsi_debug.c --- a/drivers/scsi/scsi_debug.c Thu Dec 20 13:12:43 2007 +1100 +++ b/drivers/scsi/scsi_debug.c Thu Dec 20 13:39:24 2007 +1100 @@ -601,16 +601,16 @@ static int fill_from_dev_buffer(struct s int k, req_len, act_len, len, active; void * kaddr; void * kaddr_off; - struct scatterlist * sg; + struct sg_ring * sg; if (0 == scp->request_bufflen) return 0; - if (NULL == scp->request_buffer) - return (DID_ERROR << 16); if (! ((scp->sc_data_direction == DMA_BIDIRECTIONAL) || (scp->sc_data_direction == DMA_FROM_DEVICE))) return (DID_ERROR << 16); - if (0 == scp->use_sg) { + if (NULL == scp->sg) { + if (NULL == scp->request_buffer) + return (DID_ERROR << 16); req_len = scp->request_bufflen; act_len = (req_len < arr_len) ? req_len : arr_len; memcpy(scp->request_buffer, arr, act_len); @@ -622,14 +622,14 @@ static int fill_from_dev_buffer(struct s } active = 1; req_len = act_len = 0; - scsi_for_each_sg(scp, sg, scp->use_sg, k) { + sg_ring_for_each(scp->sg, sg, k) { if (active) { kaddr = (unsigned char *) - kmap_atomic(sg_page(sg), KM_USER0); + kmap_atomic(sg_page(>sg[k]), KM_USER0); if (NULL == kaddr) return (DID_ERROR << 16); - kaddr_off = (unsigned char *)kaddr + sg->offset; - len = sg->length; + kaddr_off = (unsigned char *)kaddr + sg->sg[k].offset; + len = sg->sg[k].length; if ((req_len + len) > arr_len) { active = 0; len = arr_len - req_len; @@ -638,7 +638,7 @@ static int fill_from_dev_buffer(struct s kunmap_atomic(kaddr, KM_USER0); act_len += len; } - req_len += sg->length; + req_len += sg->sg[k].length; } if (scp->resid) scp->resid -= act_len; @@ -654,29 +654,29 @@ static int fetch_to_dev_buffer(struct sc int k, req_len, len, fin; void * kaddr; void * kaddr_off; - struct scatterlist * sg; + struct sg_ring * sg; if (0 == scp->request_bufflen) return 0; - if (NULL == scp->request_buffer) - return -1; if (! ((scp->sc_data_direction == DMA_BIDIRECTIONAL) || (scp->sc_data_direction == DMA_TO_DEVICE))) return -1; - if (0 == scp->use_sg) { + if (NULL == scp->sg) { + if (NULL == scp->request_buffer) + return -1; req_len = scp->request_bufflen; len = (req_len < max_arr_len) ? req_len : max_arr_len; memcpy(arr, scp->request_buffer, len); return len; } - sg = scsi_sglist(scp); req_len = fin = 0; - for (k = 0; k < scp->use_sg; ++k, sg = sg_next(sg)) { - kaddr = (unsigned char *)kmap_atomic(sg_page(sg), KM_USER0); + sg_ring_for_each(scp->sg, sg, k) { + kaddr = (unsigned char *)kmap_atomic(sg_page(>sg[k]), +KM_USER0); if (NULL == kaddr) return -1; - kaddr_off = (unsigned char *)kaddr + sg->offset; - len = sg->length; + kaddr_off = (unsigned char *)kaddr + sg->sg[k].offset; + len = sg->sg[k].length; if ((req_len + len) > max_arr_len) { len = max_arr_len - req_len; fin = 1; @@ -685,7 +685,7 @@ static int fetch_to_dev_buffer(struct sc kunmap_atomic(kaddr, KM_USER0); if (fin) return req_len + len; - req_len += sg->length; + req_len += sg->sg[k].length; } return req_len; } -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at
Re: almost daily Kernel oops with 2.6.23.9 - and now 2.6.23.11 as well
On Donnerstag, 20. Dezember 2007, you wrote: > On Thu, 2007-12-20 at 03:13 +0100, Hemmann, Volker Armin wrote: > > On Montag, 17. Dezember 2007, you wrote: > > > > and another one, this time tainted with the nvidia module: > > 5194.130985] Unable to handle kernel paging request at 0300 > > RIP: > > This really sounds like bad hardware. Either memory or the mobo/riser > card the memory is on. You might try lowering the memory timings of your > memory in BIOS. Try removing 1/2 of your memory. If it still remove the > other 1/2 and put the first 1/2 back and try again. if this is bad hardware why: - didn't this show up earlier? - did a several hour memtest run couple of weeks ago didn't show up anything? - and does stuff like compiling all of kde 3.5.8 or the latest kde4 rc finish without any problems? If it would be bad hardware, I should see segfaults left and right, right? but I don't see them. In fact, apart from the oopses the system works fine - even with the oopses the system works fine, apart from the occasional stuck ps aux And this messages: [41160.823959] kio_http_cache_[25229] general protection rip:32621f1fe9 rsp:7fff59a3d270 error:0 show up on closing konqueror tabs/Konqueror. There are no surprising exits, no apps vanishing. But I will run memtest86+ (or should I use memtest86?). Glück Auf, Volker -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 4/5] sg_ring: Convert core scsi code to sg_ring.
(Update: explicit sg member to replace use_sg indicating it's a scatter gather) Details: 1) The use_sg (and __use_sg) fields are removed: sg_rings contain their own count, and it's confusing to have two. 2) use_sg used to do double duty: if non-zero, it meant that the request_buffer actually pointed to a scatterlist. Replace this with an explicit sg member: if NULL, then request_buffer contains a pointer to the raw data. 3) The scsi_sg_count(), scsi_sglist() and scsi_bufflen() wrappers are removed. scsi_sg_count() is no longer necessary, scsi_sglist() is now cmd->sg, and scsi_bufflen should just be cmd->request_bufflen if you need it. If nothing else, the simplification of this logic shows why I prefer sg_ring over scatterlist chaining. Signed-off-by: Rusty Russell <[EMAIL PROTECTED]> diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -617,20 +617,21 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd ses->cmd_len = scmd->cmd_len; memcpy(ses->cmnd, scmd->cmnd, sizeof(scmd->cmnd)); ses->data_direction = scmd->sc_data_direction; + ses->sg = scmd->sg; ses->bufflen = scmd->request_bufflen; ses->buffer = scmd->request_buffer; - ses->use_sg = scmd->use_sg; ses->resid = scmd->resid; ses->result = scmd->result; if (sense_bytes) { scmd->request_bufflen = min_t(unsigned, sizeof(scmd->sense_buffer), sense_bytes); - sg_init_one(>sense_sgl, scmd->sense_buffer, - scmd->request_bufflen); - scmd->request_buffer = >sense_sgl; + + sg_ring_single(>sense_sg.ring, scmd->sense_buffer, + scmd->request_bufflen); + scmd->sg = >sense_sg.ring; + scmd->request_buffer = NULL; scmd->sc_data_direction = DMA_FROM_DEVICE; - scmd->use_sg = 1; memset(scmd->cmnd, 0, sizeof(scmd->cmnd)); scmd->cmnd[0] = REQUEST_SENSE; scmd->cmnd[4] = scmd->request_bufflen; @@ -639,7 +640,7 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd scmd->request_buffer = NULL; scmd->request_bufflen = 0; scmd->sc_data_direction = DMA_NONE; - scmd->use_sg = 0; + scmd->sg = NULL; if (cmnd) { memset(scmd->cmnd, 0, sizeof(scmd->cmnd)); memcpy(scmd->cmnd, cmnd, cmnd_size); @@ -678,7 +679,7 @@ void scsi_eh_restore_cmnd(struct scsi_cm scmd->sc_data_direction = ses->data_direction; scmd->request_bufflen = ses->bufflen; scmd->request_buffer = ses->buffer; - scmd->use_sg = ses->use_sg; + scmd->sg = ses->sg; scmd->resid = ses->resid; scmd->result = ses->result; } diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include @@ -737,21 +737,41 @@ static inline unsigned int scsi_sgtable_ return index; } -struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask) +static void free_sgring(struct sg_ring *head) { struct scsi_host_sg_pool *sgp; - struct scatterlist *sgl, *prev, *ret; + struct sg_ring *sg, *n; + + /* Free any other entries in the ring. */ + list_for_each_entry_safe(sg, n, >list, list) { + list_del(>list); + sgp = scsi_sg_pools + scsi_sgtable_index(sg->max); + mempool_free(sg, sgp->pool); + } + + /* Now free the head of the ring. */ + BUG_ON(!list_empty(>list)); + + sgp = scsi_sg_pools + scsi_sgtable_index(head->max); + mempool_free(head, sgp->pool); +} + +struct sg_ring *scsi_alloc_sgring(struct scsi_cmnd *cmd, unsigned int num, + gfp_t gfp_mask) +{ + struct scsi_host_sg_pool *sgp; + struct sg_ring *sg, *ret; unsigned int index; int this, left; - BUG_ON(!cmd->use_sg); + BUG_ON(!num); - left = cmd->use_sg; - ret = prev = NULL; + left = num; + ret = NULL; do { this = left; if (this > SCSI_MAX_SG_SEGMENTS) { - this = SCSI_MAX_SG_SEGMENTS - 1; + this = SCSI_MAX_SG_SEGMENTS; index = SG_MEMPOOL_NR - 1; } else index = scsi_sgtable_index(this); @@ -760,32 +780,20 @@ struct scatterlist *scsi_alloc_sgtable(s sgp = scsi_sg_pools + index; - sgl = mempool_alloc(sgp->pool, gfp_mask); - if (unlikely(!sgl)) + sg = mempool_alloc(sgp->pool, gfp_mask); +
[PATCH 3/5] blk_rq_map_sg_ring as a counterpart to blk_rq_map_sg.
Obvious counterpart to blk_rq_map_sg. Signed-off-by: Rusty Russell <[EMAIL PROTECTED]> diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c --- a/block/ll_rw_blk.c +++ b/block/ll_rw_blk.c @@ -31,6 +31,7 @@ #include #include #include +#include /* * for max sense size @@ -1364,6 +1365,68 @@ new_segment: EXPORT_SYMBOL(blk_rq_map_sg); +/** + * blk_rq_map_sg_ring - map a request to a scatterlist ring. + * @q: the request queue this request applies to. + * @rq: the request to map + * @sg: the sg_ring to populate. + * + * There must be enough elements in the sg_ring(s) to map the request. + */ +void blk_rq_map_sg_ring(struct request_queue *q, struct request *rq, + struct sg_ring *sg) +{ + struct bio_vec *bvec, *bvprv; + struct req_iterator iter; + int i, cluster; + struct sg_ring *head = sg; + struct scatterlist *sgprv; + + i = 0; + cluster = q->queue_flags & (1 << QUEUE_FLAG_CLUSTER); + + /* +* for each bio in rq +*/ + bvprv = NULL; + sgprv = NULL; + rq_for_each_segment(bvec, rq, iter) { + int nbytes = bvec->bv_len; + + if (bvprv && cluster) { + if (sgprv->length + nbytes > q->max_segment_size) + goto new_segment; + + if (!BIOVEC_PHYS_MERGEABLE(bvprv, bvec)) + goto new_segment; + if (!BIOVEC_SEG_BOUNDARY(q, bvprv, bvec)) + goto new_segment; + + sgprv->length += nbytes; + } else { +new_segment: + sg_set_page(sg->sg + i, bvec->bv_page, nbytes, + bvec->bv_offset); + sgprv = sg->sg + i; + if (++i == sg->max) { + sg->num = i; + sg = sg_ring_next(sg, head); + i = 0; + } + } + bvprv = bvec; + } /* segments in rq */ + + /* If we were still working on an sg_ring, set the number and +* clear any following sg_rings. */ + if (sg) { + sg->num = i; + for (sg = sg_ring_next(sg,head); sg; sg = sg_ring_next(sg,head)) + sg->num = 0; + } +} +EXPORT_SYMBOL(blk_rq_map_sg_ring); + /* * the standard queue merge functions, can be overridden with device * specific ones if so desired diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -777,6 +777,8 @@ extern void blk_ordered_complete_seq(str extern void blk_ordered_complete_seq(struct request_queue *, unsigned, int); extern int blk_rq_map_sg(struct request_queue *, struct request *, struct scatterlist *); +struct sg_ring; +extern void blk_rq_map_sg_ring(struct request_queue *, struct request *, struct sg_ring *); extern void blk_dump_rq_flags(struct request *, char *); extern void generic_unplug_device(struct request_queue *); extern void __generic_unplug_device(struct request_queue *); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 2/5] dma_map_sg_ring() helper
Obvious counterpart to dma_map_sg. Note that this is arch-independent code; sg_rings are backwards compatible with simple sg arrays. Signed-off-by: Rusty Russell <[EMAIL PROTECTED]> --- drivers/base/dma-mapping.c | 13 + include/linux/dma-mapping.h |4 2 files changed, 17 insertions(+), 0 deletions(-) diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c --- a/drivers/base/dma-mapping.c +++ b/drivers/base/dma-mapping.c @@ -8,6 +8,7 @@ */ #include +#include /* * Managed DMA API @@ -162,6 +163,59 @@ void dmam_free_noncoherent(struct device } EXPORT_SYMBOL(dmam_free_noncoherent); +/** + * dma_map_sg_ring - Map an entire sg ring + * @dev: Device to free noncoherent memory for + * @sg: The sg_ring + * @direction: DMA_TO_DEVICE, DMA_FROM_DEVICE or DMA_BIDIRECTIONAL. + * + * This returns -ENOMEM if mapping fails. It's not clear that telling you + * it failed is useful though. + */ +int dma_map_sg_ring(struct device *dev, struct sg_ring *sg, +enum dma_data_direction direction) +{ + struct sg_ring *i; + unsigned int num; + + for (i = sg; i; i = sg_ring_next(i, sg)) { + BUG_ON(i->num > i->max); + num = dma_map_sg(dev, i->sg, i->num, direction); + if (num == 0 && i->num != 0) + goto unmap; + } + return 0; + +unmap: + while (sg) { + dma_unmap_sg(dev, sg->sg, sg->num, direction); + sg = sg_ring_next(sg, i); + } + return -ENOMEM; + +} +EXPORT_SYMBOL(dma_map_sg_ring); + +/** + * dma_unmap_sg_ring - Unmap an entire sg ring + * @dev: Device to free noncoherent memory for + * @sg: The sg_ring + * @direction: DMA_TO_DEVICE, DMA_FROM_DEVICE or DMA_BIDIRECTIONAL. + * + * Call after dma_map_sg_ring() succeeds. + */ +void dma_unmap_sg_ring(struct device *dev, struct sg_ring *sg, + enum dma_data_direction direction) +{ + struct sg_ring *i; + + for (i = sg; i; i = sg_ring_next(i, sg)) { + BUG_ON(i->num > i->max); + dma_unmap_sg(dev, i->sg, i->num, direction); + } +} +EXPORT_SYMBOL(dma_unmap_sg_ring); + #ifdef ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY static void dmam_coherent_decl_release(struct device *dev, void *res) diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h @@ -87,6 +87,12 @@ dma_mark_declared_memory_occupied(struct } #endif +struct sg_ring; +extern int dma_map_sg_ring(struct device *dev, struct sg_ring *sg, + enum dma_data_direction direction); +extern void dma_unmap_sg_ring(struct device *dev, struct sg_ring *sg, + enum dma_data_direction direction); + /* * Managed DMA API */ -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 1/5] sg_ring: sg_ring.h
(Updates since last time: const-safe iterators and sg_ring_num helper for counting scatterlist entries across entire ring). This patch introduces 'struct sg_ring', a layer on top of scatterlist arrays. It meshes nicely with routines which expect a simple array of 'struct scatterlist' because it is easy to break down the ring into its constituent arrays. The sg_ring header also encodes the maximum number of entries, useful for routines which populate an sg. We need never hand around a number of elements any more. Signed-off-by: Rusty Russell <[EMAIL PROTECTED]> --- include/linux/sg_ring.h | 74 1 files changed, 74 insertions(+), 0 deletions(-) create mode 100644 include/linux/sgring.h diff --git a/include/linux/sg_ring.h b/include/linux/sg_ring.h new file mode 100644 --- /dev/null +++ b/include/linux/sg_ring.h @@ -0,0 +1,124 @@ +#ifndef _LINUX_SG_RING_H +#define _LINUX_SG_RING_H +#include + +/** + * struct sg_ring - a ring of scatterlists + * @list: the list_head chaining them together + * @num: the number of valid sg entries + * @max: the maximum number of sg entries (size of the sg array). + * @sg: the array of scatterlist entries. + * + * This provides a convenient encapsulation of one or more scatter gather + * arrays. + */ +struct sg_ring +{ + struct list_head list; + unsigned int num, max; + struct scatterlist sg[0]; +}; + +/* This helper declares an sg ring on the stack or in a struct. */ +#define DECLARE_SG_RING(name, max) \ + struct {\ + struct sg_ring ring;\ + struct scatterlist sg[max]; \ + } name + +/** + * sg_ring_init - initialize a scatterlist ring. + * @sg: the sg_ring. + * @max: the size of the trailing sg array. + * + * After initialization sg is alone in the ring. + */ +static inline void sg_ring_init(struct sg_ring *sg, unsigned int max) +{ +#ifdef CONFIG_DEBUG_SG + unsigned int i; + for (i = 0; i < max; i++) + sg->sg[i].sg_magic = SG_MAGIC; +#endif + INIT_LIST_HEAD(>list); + sg->max = max; + /* FIXME: This is to clear the page bits. */ + sg_init_table(sg->sg, sg->max); +} + +/** + * sg_ring_single - initialize a one-element scatterlist ring. + * @sg: the sg_ring. + * @buf: the pointer to the buffer. + * @buflen: the length of the buffer. + * + * Does sg_ring_init and also sets up first (and only) sg element. + */ +static inline void sg_ring_single(struct sg_ring *sg, + const void *buf, + unsigned int buflen) +{ + sg_ring_init(sg, 1); + sg->num = 1; + sg_init_one(>sg[0], buf, buflen); +} + +/** + * sg_ring_next - next array in a scatterlist ring. + * @sg: the sg_ring. + * @head: the sg_ring head. + * + * This will return NULL once @sg has looped back around to @head. + */ +static inline struct sg_ring *sg_ring_next(const struct sg_ring *sg, + const struct sg_ring *head) +{ + sg = list_first_entry(>list, struct sg_ring, list); + if (sg == head) + sg = NULL; + return (struct sg_ring *)sg; +} + +/* Helper for writing for loops. */ +static inline struct sg_ring *sg_ring_iter(const struct sg_ring *head, + const struct sg_ring *sg, + unsigned int *i) +{ + (*i)++; + /* While loop lets us skip any zero-entry sg_ring arrays */ + while (*i == sg->num) { + *i = 0; + sg = sg_ring_next(sg, head); + if (!sg) + break; + } + return (struct sg_ring *)sg; +} + +/** + * sg_ring_for_each - iterate through an entire sg_ring ring + * @head: the head of the sg_ring. + * @sg: the sg_ring iterator. + * @i: an (unsigned) integer which refers to sg->sg[i]. + * + * The current scatterlist element is sg->sg[i]. + */ +#define sg_ring_for_each(head, sg, i) \ + for (sg = head, i = 0; sg; sg = sg_ring_iter(head, sg, )) + +/** + * sg_ring_num - how many struct scatterlists are used in this sg_ring. + * @head: the sg_ring + * + * Simple helper function to add up the number of scatterlists. + */ +static inline unsigned sg_ring_num(const struct sg_ring *head) +{ + unsigned int num = 0, i; + const struct sg_ring *sg; + + sg_ring_for_each(head, sg, i) + num += sg->num; + return num; +} +#endif /* _LINUX_SG_RING_H */ -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 0/5] sg_ring for scsi
OK, some fixes since last time, as I wade through more SCSI drivers. Some drivers use "use_sg" as a flag to know whether the request_buffer is a scatterlist: I don't need the counter, but I still need the flag, so I fixed that in a more intuitive way (an explicit ->sg pointer in the cmd). Also, I've updated and tested scsi_debug, after Douglas's excellent suggestion. (I just found out about struct scsi_pointer, so I'm off to update that now, too). Cheers, Rusty. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 4/5] Convert PowerPC MPC i2c to of_platform_driver from platform_driver
On Wed, Dec 19, 2007 at 11:41:44PM -0500, Jon Smirl wrote: > Convert MPC i2c driver from being a platform_driver to an open > firmware version. Error returns were improved. Routine names were > changed from fsl_ to mpc_ to make them match the file name. In discussions BenH and I have had, we've actually concluded that moving this from platform drivers to of_platform drives is not actually a good idea. In fact we're planning to move away from of_platform devices and drivers and instead develop a framework for instantiating platform devices or i2c devices or whatever devices from the device tree nodes. -- David Gibson| I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
not needed patch
Ingo. commit fbdcf18df73758b2e187ab94678b30cd5f6ff9f9 is not needed. another patch (by you !! commit 699d934d5f958d7944d195c03c334f28cc0b3669 x86: fixup cpu_info array conversion) already removed clearing of c->cpu_index. in identify_cpu also it is not consisent to smpboot_32.c. (it will assign id to cpu_index right after *c = boot_cpu_data; ) by revert commit fbdcf18df73758b2e187ab94678b30cd5f6ff9f9, we could use c->cpu_index in identify_cpu. YH commit fbdcf18df73758b2e187ab94678b30cd5f6ff9f9 Author: Mike Travis <[EMAIL PROTECTED]> Date: Wed Dec 19 23:20:19 2007 +0100 x86: fix show cpuinfo cpu number always zero when called by setup_arch) after smp_store_cpu_info() had set it to the correct value. The error shows up in 'cat /proc/cpuinfo' will all cpus = 0. Signed-off-by: Mike Travis <[EMAIL PROTECTED]> Cc: Andi Kleen <[EMAIL PROTECTED]> Cc: Christoph Lameter <[EMAIL PROTECTED]> Cc: Jack Steiner <[EMAIL PROTECTED]> Cc: Suresh B Siddha <[EMAIL PROTECTED]> Signed-off-by: Andrew Morton <[EMAIL PROTECTED]> Signed-off-by: Ingo Molnar <[EMAIL PROTECTED]> Signed-off-by: Thomas Gleixner <[EMAIL PROTECTED]> diff --git a/arch/x86/kernel/smpboot_64.c b/arch/x86/kernel/smpboot_64.c index 500670c..5948895 100644 --- a/arch/x86/kernel/smpboot_64.c +++ b/arch/x86/kernel/smpboot_64.c @@ -141,8 +141,8 @@ static void __cpuinit smp_store_cpu_info(int id) struct cpuinfo_x86 *c = _data(id); *c = boot_cpu_data; - c->cpu_index = id; identify_cpu(c); + c->cpu_index = id; print_cpu_info(c); } -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: OOPS: 2.6.24-rc5-mm1 -- EIP is at r_show+0x2a/0x70 -- (triggered by "cat /proc/iomem")
Okay. The command that directly triggers this is: cat /proc/iomem Here is the stack trace without the line-wrapping (sorry!): [ 251.602965] wlan0_rename: RX non-WEP frame, but expected encryption [ 252.868386] BUG: unable to handle kernel NULL pointer dereference at virtual address 0018 [ 252.868393] printing ip: c012d527 *pde = [ 252.868399] Oops: [#1] SMP [ 252.868403] last sysfs file: /sys/devices/pci:00/:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda3/stat [ 252.868407] Modules linked in: aes_i586 aes_generic i915 drm rfcomm l2cap bluetooth acpi_cpufreq cpufreq_stats cpufreq_conservative sbs sbshc dm_crypt sbp2 parport_pc lp parport arc4 ecb crypto_blkcipher cryptomgr crypto_algapi snd_hda_intel snd_pcm_oss snd_mixer_oss pcmcia snd_pcm iTCO_wdt iTCO_vendor_support snd_seq_dummy watchdog_core watchdog_dev snd_seq_oss snd_seq_midi tifm_7xx1 snd_rawmidi iwl3945 snd_seq_midi_event rng_core tifm_core mac80211 snd_seq snd_timer snd_seq_device cfg80211 sky2 battery yenta_socket rsrc_nonstatic pcmcia_core ac snd soundcore snd_page_alloc button shpchp pci_hotplug sr_mod cdrom pata_acpi piix ide_core firewire_ohci firewire_core crc_itu_t thermal processor fan [ 252.868469] [ 252.868472] Pid: 7088, comm: head Not tainted (2.6.24-rc5-mm1 #9) [ 252.868476] EIP: 0060:[] EFLAGS: 00010297 CPU: 0 [ 252.868481] EIP is at r_show+0x2a/0x70 [ 252.868483] EAX: EBX: 0001 ECX: c07e3224 EDX: c04bb034 [ 252.868486] ESI: 0008 EDI: ed1f52c0 EBP: f5320f10 ESP: f5320f04 [ 252.868489] DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068 [ 252.868493] Process head (pid: 7088, ti=f532 task=f532e000 task.ti=f532) [ 252.868495] Stack: c03a6cac ed1f52c0 c07e3224 f5320f50 c0199a7e 2000 bf930807 e1007800 [ 252.868504]ed1f52e0 01d3 000e 000d [ 252.868512]fffb f7d39370 c01998e4 f5320f74 c01af4f5 f5320f9c 2000 bf930807 [ 252.868521] Call Trace: [ 252.868523] [] show_trace_log_lvl+0x12/0x25 [ 252.868529] [] show_stack_log_lvl+0x8a/0x95 [ 252.868534] [] show_registers+0x8c/0x154 [ 252.868538] [] die+0x10e/0x1d2 [ 252.868542] [] do_page_fault+0x52b/0x600 [ 252.868547] [] error_code+0x72/0x78 [ 252.868552] [] seq_read+0x19a/0x26c [ 252.868557] [] proc_reg_read+0x60/0x74 [ 252.868562] [] vfs_read+0xa2/0x11e [ 252.868567] [] sys_read+0x3b/0x60 [ 252.868571] [] sysenter_past_esp+0x6b/0xc1 [ 252.868575] === [ 252.868577] Code: c3 55 89 d1 89 e5 57 89 c7 56 53 8b 50 64 83 7a 0c 00 77 0e 81 7a 08 ff ff 00 00 be 04 00 00 00 76 05 be 08 00 00 00 89 c8 31 db <8b> 40 18 39 d0 74 06 43 83 fb 05 75 f3 8b 41 10 ba 2f 1b 45 c0 [ 252.868623] EIP: [] r_show+0x2a/0x70 SS:ESP 0068:f5320f04 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 4/5] Convert PowerPC MPC i2c to of_platform_driver from platform_driver
Convert MPC i2c driver from being a platform_driver to an open firmware version. Error returns were improved. Routine names were changed from fsl_ to mpc_ to make them match the file name. Signed-off-by: Jon Smirl <[EMAIL PROTECTED]> --- arch/powerpc/sysdev/fsl_soc.c | 96 -- drivers/i2c/busses/i2c-mpc.c | 183 - 2 files changed, 180 insertions(+), 99 deletions(-) diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c index 268638a..d6ef264 100644 --- a/arch/powerpc/sysdev/fsl_soc.c +++ b/arch/powerpc/sysdev/fsl_soc.c @@ -318,102 +318,6 @@ err: arch_initcall(gfar_of_init); -#ifdef CONFIG_I2C_BOARDINFO -#include - -static void __init of_register_i2c_devices(struct device_node *adap_node, - int bus_num) -{ - struct device_node *node = NULL; - const char *compatible; - - while ((node = of_get_next_child(adap_node, node))) { - struct i2c_board_info info = {}; - const u32 *addr; - int len; - - addr = of_get_property(node, "reg", ); - if (!addr || len < sizeof(int) || *addr > (1 << 10) - 1) { - printk(KERN_WARNING "fsl_soc.c: invalid i2c device entry\n"); - continue; - } - - info.irq = irq_of_parse_and_map(node, 0); - if (info.irq == NO_IRQ) - info.irq = -1; - - compatible = of_get_property(node, "compatible", ); - if (!compatible) { - printk(KERN_WARNING "i2c-mpc.c: invalid entry, missing compatible attribute\n"); - continue; - } - strncpy(info.driver_name, compatible, sizeof(info.driver_name)); - - info.addr = *addr; - - i2c_register_board_info(bus_num, , 1); - } -} - -static int __init fsl_i2c_of_init(void) -{ - struct device_node *np; - unsigned int i; - struct platform_device *i2c_dev; - int ret; - - for (np = NULL, i = 0; -(np = of_find_compatible_node(np, "i2c", "fsl-i2c")) != NULL; -i++) { - struct resource r[2]; - struct fsl_i2c_platform_data i2c_data; - const unsigned char *flags = NULL; - - memset(, 0, sizeof(r)); - memset(_data, 0, sizeof(i2c_data)); - - ret = of_address_to_resource(np, 0, [0]); - if (ret) - goto err; - - of_irq_to_resource(np, 0, [1]); - - i2c_dev = platform_device_register_simple("fsl-i2c", i, r, 2); - if (IS_ERR(i2c_dev)) { - ret = PTR_ERR(i2c_dev); - goto err; - } - - i2c_data.device_flags = 0; - flags = of_get_property(np, "dfsrr", NULL); - if (flags) - i2c_data.device_flags |= FSL_I2C_DEV_SEPARATE_DFSRR; - - flags = of_get_property(np, "fsl5200-clocking", NULL); - if (flags) - i2c_data.device_flags |= FSL_I2C_DEV_CLOCK_5200; - - ret = - platform_device_add_data(i2c_dev, _data, -sizeof(struct - fsl_i2c_platform_data)); - if (ret) - goto unreg; - - of_register_i2c_devices(np, i); - } - - return 0; - -unreg: - platform_device_unregister(i2c_dev); -err: - return ret; -} - -arch_initcall(fsl_i2c_of_init); -#endif - #ifdef CONFIG_PPC_83xx static int __init mpc83xx_wdt_init(void) { diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index 7c35a8f..4f2e7ea 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include @@ -25,13 +25,13 @@ #include #include -#define MPC_I2C_ADDR 0x00 +#define DRV_NAME "mpc-i2c" + #define MPC_I2C_FDR0x04 #define MPC_I2C_CR 0x08 #define MPC_I2C_SR 0x0c #define MPC_I2C_DR 0x10 #define MPC_I2C_DFSRR 0x14 -#define MPC_I2C_REGION 0x20 #define CCR_MEN 0x80 #define CCR_MIEN 0x40 @@ -316,6 +316,181 @@ static struct i2c_adapter mpc_ops = { .retries = 1 }; +struct i2c_driver_device { + char*of_device; + char*i2c_driver; + char*i2c_type; +}; + +#ifdef CONFIG_PPC_MERGE + +static void of_register_i2c_devices(struct i2c_adapter *adap, struct device_node *adap_node) +{ + struct device_node *node = NULL; + + while ((node = of_get_next_child(adap_node, node))) { + struct i2c_board_info info; + const u32 *addr; + const char *compatible; + int len; + +
[PATCH 2/5] Modify several rtc drivers to use the alias names list property of i2c
This patch modifies the ds1307, ds1374, and rs5c372 i2c drivers to support device tree names using the new i2c mod alias support Signed-off-by: Jon Smirl <[EMAIL PROTECTED]> --- arch/powerpc/sysdev/fsl_soc.c | 44 drivers/rtc/rtc-ds1307.c | 20 +- drivers/rtc/rtc-ds1374.c |9 ++ drivers/rtc/rtc-m41t80.c | 57 - drivers/rtc/rtc-rs5c372.c | 16 ++-- 5 files changed, 85 insertions(+), 61 deletions(-) diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c index 3ace747..268638a 100644 --- a/arch/powerpc/sysdev/fsl_soc.c +++ b/arch/powerpc/sysdev/fsl_soc.c @@ -320,48 +320,12 @@ arch_initcall(gfar_of_init); #ifdef CONFIG_I2C_BOARDINFO #include -struct i2c_driver_device { - char*of_device; - char*i2c_driver; - char*i2c_type; -}; - -static struct i2c_driver_device i2c_devices[] __initdata = { - {"ricoh,rs5c372a", "rtc-rs5c372", "rs5c372a",}, - {"ricoh,rs5c372b", "rtc-rs5c372", "rs5c372b",}, - {"ricoh,rv5c386", "rtc-rs5c372", "rv5c386",}, - {"ricoh,rv5c387a", "rtc-rs5c372", "rv5c387a",}, - {"dallas,ds1307", "rtc-ds1307", "ds1307",}, - {"dallas,ds1337", "rtc-ds1307", "ds1337",}, - {"dallas,ds1338", "rtc-ds1307", "ds1338",}, - {"dallas,ds1339", "rtc-ds1307", "ds1339",}, - {"dallas,ds1340", "rtc-ds1307", "ds1340",}, - {"stm,m41t00", "rtc-ds1307", "m41t00"}, - {"dallas,ds1374", "rtc-ds1374", "rtc-ds1374",}, -}; - -static int __init of_find_i2c_driver(struct device_node *node, -struct i2c_board_info *info) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(i2c_devices); i++) { - if (!of_device_is_compatible(node, i2c_devices[i].of_device)) - continue; - if (strlcpy(info->driver_name, i2c_devices[i].i2c_driver, - KOBJ_NAME_LEN) >= KOBJ_NAME_LEN || - strlcpy(info->type, i2c_devices[i].i2c_type, - I2C_NAME_SIZE) >= I2C_NAME_SIZE) - return -ENOMEM; - return 0; - } - return -ENODEV; -} static void __init of_register_i2c_devices(struct device_node *adap_node, int bus_num) { struct device_node *node = NULL; + const char *compatible; while ((node = of_get_next_child(adap_node, node))) { struct i2c_board_info info = {}; @@ -378,8 +342,12 @@ static void __init of_register_i2c_devices(struct device_node *adap_node, if (info.irq == NO_IRQ) info.irq = -1; - if (of_find_i2c_driver(node, ) < 0) + compatible = of_get_property(node, "compatible", ); + if (!compatible) { + printk(KERN_WARNING "i2c-mpc.c: invalid entry, missing compatible attribute\n"); continue; + } + strncpy(info.driver_name, compatible, sizeof(info.driver_name)); info.addr = *addr; diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index bc1c7fe..d4874ff 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c @@ -139,6 +139,17 @@ static inline const struct chip_desc *find_chip(const char *s) return NULL; } +static struct i2c_device_id ds1307_id[] = { + OF_I2C_ID("dallas,ds1307", ds_1307) + OF_I2C_ID("dallas,ds1337", ds_1337) + OF_I2C_ID("dallas,ds1338", ds_1338) + OF_I2C_ID("dallas,ds1339", ds_1339) + OF_I2C_ID("dallas,ds1340", ds_1340) + OF_I2C_ID("stm,m41t00", m41t00) + {}, +}; +MODULE_DEVICE_TABLE(i2c, ds1307_id); + static int ds1307_get_time(struct device *dev, struct rtc_time *t) { struct ds1307 *ds1307 = dev_get_drvdata(dev); @@ -326,7 +337,7 @@ static struct bin_attribute nvram = { static struct i2c_driver ds1307_driver; -static int __devinit ds1307_probe(struct i2c_client *client) +static int __devinit ds1307_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct ds1307 *ds1307; int err = -ENODEV; @@ -334,7 +345,11 @@ static int __devinit ds1307_probe(struct i2c_client *client) const struct chip_desc *chip; struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); - chip = find_chip(client->name); + if (id) + chip = [id->driver_data]; + else + chip = find_chip(client->name); + if (!chip) { dev_err(>dev, "unknown chip type '%s'\n", client->name); @@ -537,6 +552,7 @@ static struct i2c_driver ds1307_driver = { }, .probe = ds1307_probe, .remove = __devexit_p(ds1307_remove), + .id_table
[PATCH 1/5] Implement module aliasing for i2c to translate from device tree names
This patch allows new style i2c chip drivers to have alias names using the official kernel aliasing system and MODULE_DEVICE_TABLE(). I've tested it on PowerPC and x86. This change is required for PowerPC device tree support. Signed-off-by: Jon Smirl <[EMAIL PROTECTED]> --- drivers/i2c/i2c-core.c | 32 ++-- include/linux/i2c.h |9 - include/linux/mod_devicetable.h | 20 scripts/mod/file2alias.c| 19 +++ 4 files changed, 69 insertions(+), 11 deletions(-) diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index b5e13e4..fce06fd 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c @@ -47,10 +47,25 @@ static DEFINE_IDR(i2c_adapter_idr); /* - */ -static int i2c_device_match(struct device *dev, struct device_driver *drv) +static const struct i2c_device_id *i2c_device_match(const struct i2c_device_id *id, struct i2c_client *client) +{ + /* only powerpc drivers implement the id_table, +* it is empty on other platforms */ + if (id) { + while (id->name[0]) { + if (strcmp(client->driver_name, id->name) == 0) + return id; + id++; + } + } + return NULL; +} + +static int i2c_bus_match(struct device *dev, struct device_driver *drv) { struct i2c_client *client = to_i2c_client(dev); struct i2c_driver *driver = to_i2c_driver(drv); + const struct i2c_device_id *found_id; /* make legacy i2c drivers bypass driver model probing entirely; * such drivers scan each i2c adapter/bus themselves. @@ -58,9 +73,11 @@ static int i2c_device_match(struct device *dev, struct device_driver *drv) if (!is_newstyle_driver(driver)) return 0; - /* new style drivers use the same kind of driver matching policy -* as platform devices or SPI: compare device and driver IDs. -*/ + /* match on an id table if there is one */ + found_id = i2c_device_match(driver->id_table, client); + if (found_id) + return 1; + return strcmp(client->driver_name, drv->name) == 0; } @@ -89,12 +106,15 @@ static int i2c_device_probe(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct i2c_driver *driver = to_i2c_driver(dev->driver); + const struct i2c_device_id *id; if (!driver->probe) return -ENODEV; client->driver = driver; dev_dbg(dev, "probe\n"); - return driver->probe(client); + + id = i2c_device_match(driver->id_table, client); + return driver->probe(client, id); } static int i2c_device_remove(struct device *dev) @@ -189,7 +209,7 @@ static struct device_attribute i2c_dev_attrs[] = { static struct bus_type i2c_bus_type = { .name = "i2c", .dev_attrs = i2c_dev_attrs, - .match = i2c_device_match, + .match = i2c_bus_match, .uevent = i2c_device_uevent, .probe = i2c_device_probe, .remove = i2c_device_remove, diff --git a/include/linux/i2c.h b/include/linux/i2c.h index a100c9f..49fc682 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -126,7 +126,7 @@ struct i2c_driver { * With the driver model, device enumeration is NEVER done by drivers; * it's done by infrastructure. (NEW STYLE DRIVERS ONLY) */ - int (*probe)(struct i2c_client *); + int (*probe)(struct i2c_client *, const struct i2c_device_id *id); int (*remove)(struct i2c_client *); /* driver model interfaces that don't relate to enumeration */ @@ -141,11 +141,10 @@ struct i2c_driver { struct device_driver driver; struct list_head list; + struct i2c_device_id *id_table; }; #define to_i2c_driver(d) container_of(d, struct i2c_driver, driver) -#define I2C_NAME_SIZE 20 - /** * struct i2c_client - represent an I2C slave device * @flags: I2C_CLIENT_TEN indicates the device uses a ten bit chip address; @@ -179,7 +178,7 @@ struct i2c_client { /* to the client*/ struct device dev; /* the device structure */ int irq;/* irq issued by device (or -1) */ - char driver_name[KOBJ_NAME_LEN]; + char driver_name[I2C_NAME_SIZE]; struct list_head list; struct completion released; }; @@ -223,7 +222,7 @@ static inline void i2c_set_clientdata (struct i2c_client *dev, void *data) * with the adapter already known. */ struct i2c_board_info { - chardriver_name[KOBJ_NAME_LEN]; + chardriver_name[I2C_NAME_SIZE]; char
[PATCH 0/5] Version 17, series to add device tree naming to i2c
Since copying i2c-mpc.c to maintain support for the ppc architecture seems to be an issue; instead rework i2c-mpc.c to use CONFIG_PPC_MERGE #ifdefs to support both the ppc and powerpc architecture. When ppc is deleted in six months these #ifdefs will need to be removed. Another rework of the i2c for powerpc device tree patch. This version implements standard alias naming only on the powerpc platform and only for the device tree names. The old naming mechanism of i2c_client.name,driver_name is left in place and not changed for non-powerpc platforms. This patch is fully capable of dynamically loading the i2c modules. You can modprobe in the i2c-mpc driver and the i2c modules described in the device tree will be automatically loaded. Modules also work if compiled in. The follow on patch to module-init-tools is also needed since the i2c subsystem has never implemented dynamic loading. The following series implements standard linux module aliasing for i2c modules on arch=powerpc. It then converts the mpc i2c driver from being a platform driver to an open firmware one. I2C device names are picked up from the device tree. Module aliasing is used to translate from device tree names into to linux kernel names. Several i2c drivers are updated to use the new aliasing. -- Jon Smirl [EMAIL PROTECTED] -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 5/5] Convert pfc8563 i2c driver from old style to new style
Convert pfc8563 i2c driver from old style to new style. The driver is also modified to support device tree names via the i2c mod alias mechanism. Signed-off-by: Jon Smirl <[EMAIL PROTECTED]> --- drivers/rtc/rtc-pcf8563.c | 107 +++-- 1 files changed, 27 insertions(+), 80 deletions(-) diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c index 0242d80..e1ea2a0 100644 --- a/drivers/rtc/rtc-pcf8563.c +++ b/drivers/rtc/rtc-pcf8563.c @@ -25,10 +25,6 @@ * located at 0x51 will pass the validation routine due to * the way the registers are implemented. */ -static unsigned short normal_i2c[] = { I2C_CLIENT_END }; - -/* Module parameters */ -I2C_CLIENT_INSMOD; #define PCF8563_REG_ST10x00 /* status */ #define PCF8563_REG_ST20x01 @@ -72,9 +68,6 @@ struct pcf8563 { int c_polarity; /* 0: MO_C=1 means 19xx, otherwise MO_C=1 means 20xx */ }; -static int pcf8563_probe(struct i2c_adapter *adapter, int address, int kind); -static int pcf8563_detach(struct i2c_client *client); - /* * In the routines that deal directly with the pcf8563 hardware, we use * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch. @@ -257,98 +250,52 @@ static const struct rtc_class_ops pcf8563_rtc_ops = { .set_time = pcf8563_rtc_set_time, }; -static int pcf8563_attach(struct i2c_adapter *adapter) +static int pcf8563_remove(struct i2c_client *client) { - return i2c_probe(adapter, _data, pcf8563_probe); + struct rtc_device *rtc = i2c_get_clientdata(client); + + if (rtc) + rtc_device_unregister(rtc); + + return 0; } +static struct i2c_device_id pcf8563_id[] = { + OF_I2C_ID("philips,pcf8563", 0) + OF_I2C_ID("epson,rtc8564", 0) + {}, +}; +MODULE_DEVICE_TABLE(i2c, pcf8563_id); + +static int pcf8563_probe(struct i2c_client *client, const struct i2c_device_id *id); + static struct i2c_driver pcf8563_driver = { .driver = { - .name = "pcf8563", + .name = "rtc-pcf8563", }, .id = I2C_DRIVERID_PCF8563, - .attach_adapter = _attach, - .detach_client = _detach, + .probe = _probe, + .remove = _remove, + .id_table = pcf8563_id, }; -static int pcf8563_probe(struct i2c_adapter *adapter, int address, int kind) +static int pcf8563_probe(struct i2c_client *client, const struct i2c_device_id *id) { - struct pcf8563 *pcf8563; - struct i2c_client *client; + int result; struct rtc_device *rtc; - int err = 0; - - dev_dbg(>dev, "%s\n", __FUNCTION__); - - if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) { - err = -ENODEV; - goto exit; - } - - if (!(pcf8563 = kzalloc(sizeof(struct pcf8563), GFP_KERNEL))) { - err = -ENOMEM; - goto exit; - } - - client = >client; - client->addr = address; - client->driver = _driver; - client->adapter = adapter; - - strlcpy(client->name, pcf8563_driver.driver.name, I2C_NAME_SIZE); - - /* Verify the chip is really an PCF8563 */ - if (kind < 0) { - if (pcf8563_validate_client(client) < 0) { - err = -ENODEV; - goto exit_kfree; - } - } - - /* Inform the i2c layer */ - if ((err = i2c_attach_client(client))) - goto exit_kfree; - - dev_info(>dev, "chip found, driver version " DRV_VERSION "\n"); + result = pcf8563_validate_client(client); + if (result) + return result; rtc = rtc_device_register(pcf8563_driver.driver.name, >dev, _rtc_ops, THIS_MODULE); - - if (IS_ERR(rtc)) { - err = PTR_ERR(rtc); - goto exit_detach; - } + if (IS_ERR(rtc)) + return PTR_ERR(rtc); i2c_set_clientdata(client, rtc); return 0; - -exit_detach: - i2c_detach_client(client); - -exit_kfree: - kfree(pcf8563); - -exit: - return err; -} - -static int pcf8563_detach(struct i2c_client *client) -{ - struct pcf8563 *pcf8563 = container_of(client, struct pcf8563, client); - int err; - struct rtc_device *rtc = i2c_get_clientdata(client); - - if (rtc) - rtc_device_unregister(rtc); - - if ((err = i2c_detach_client(client))) - return err; - - kfree(pcf8563); - - return 0; } static int __init pcf8563_init(void) -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 3/5] Clean up error returns
Return errors that were being ignored in the mpc-i2c driver Signed-off-by: Jon Smirl <[EMAIL PROTECTED]> --- drivers/i2c/busses/i2c-mpc.c | 30 +- 1 files changed, 17 insertions(+), 13 deletions(-) diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index d8de4ac..7c35a8f 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -180,7 +180,7 @@ static void mpc_i2c_stop(struct mpc_i2c *i2c) static int mpc_write(struct mpc_i2c *i2c, int target, const u8 * data, int length, int restart) { - int i; + int i, result; unsigned timeout = i2c->adap.timeout; u32 flags = restart ? CCR_RSTA : 0; @@ -192,15 +192,17 @@ static int mpc_write(struct mpc_i2c *i2c, int target, /* Write target byte */ writeb((target << 1), i2c->base + MPC_I2C_DR); - if (i2c_wait(i2c, timeout, 1) < 0) - return -1; + result = i2c_wait(i2c, timeout, 1); + if (result < 0) + return result; for (i = 0; i < length; i++) { /* Write data byte */ writeb(data[i], i2c->base + MPC_I2C_DR); - if (i2c_wait(i2c, timeout, 1) < 0) - return -1; + result = i2c_wait(i2c, timeout, 1); + if (result < 0) + return result; } return 0; @@ -210,7 +212,7 @@ static int mpc_read(struct mpc_i2c *i2c, int target, u8 * data, int length, int restart) { unsigned timeout = i2c->adap.timeout; - int i; + int i, result; u32 flags = restart ? CCR_RSTA : 0; /* Start with MEN */ @@ -221,8 +223,9 @@ static int mpc_read(struct mpc_i2c *i2c, int target, /* Write target address byte - this time with the read flag set */ writeb((target << 1) | 1, i2c->base + MPC_I2C_DR); - if (i2c_wait(i2c, timeout, 1) < 0) - return -1; + result = i2c_wait(i2c, timeout, 1); + if (result < 0) + return result; if (length) { if (length == 1) @@ -234,8 +237,9 @@ static int mpc_read(struct mpc_i2c *i2c, int target, } for (i = 0; i < length; i++) { - if (i2c_wait(i2c, timeout, 0) < 0) - return -1; + result = i2c_wait(i2c, timeout, 0); + if (result < 0) + return result; /* Generate txack on next to last byte */ if (i == length - 2) @@ -321,9 +325,9 @@ static int fsl_i2c_probe(struct platform_device *pdev) pdata = (struct fsl_i2c_platform_data *) pdev->dev.platform_data; - if (!(i2c = kzalloc(sizeof(*i2c), GFP_KERNEL))) { + i2c = kzalloc(sizeof(*i2c), GFP_KERNEL); + if (!i2c) return -ENOMEM; - } i2c->irq = platform_get_irq(pdev, 0); if (i2c->irq < 0) { @@ -381,7 +385,7 @@ static int fsl_i2c_remove(struct platform_device *pdev) i2c_del_adapter(>adap); platform_set_drvdata(pdev, NULL); - if (i2c->irq != 0) + if (i2c->irq != NO_IRQ) free_irq(i2c->irq, i2c); iounmap(i2c->base); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
OOPS: 2.6.24-rc5-mm1 -- EIP is at r_show+0x2a/0x70
I have the patch "find /proc | xargs tail" [ 50.595474] ADDRCONF(NETDEV_UP): eth0: link is not ready [ 54.733829] BUG: unable to handle kernel NULL pointer dereference at virtual address 0018 [ 54.733836] printing ip: c012d527 *pde = [ 54.733843] Oops: [#1] SMP [ 54.733847] last sysfs file: /sys/devices/pci:00/:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda3/stat [ 54.733851] Modules linked in: aes_i586 aes_generic i915 drm rfcomm l2cap bluetooth acpi_cpufreq cpufreq_stats cpufreq_conservative sbs sbshc dm_crypt sbp2 parport_pc lp parport arc4 ecb crypto_blkcipher cryptomgr crypto_algapi pcmcia snd_hda_intel snd_pcm_oss snd_mixer_oss iwl3945 snd_pcm snd_seq_dumm y mac80211 snd_seq_oss cfg80211 sky2 tifm_7xx1 yenta_socket rsrc_nonstatic pcmcia_core tifm_core iTCO_wdt iTCO_vendor_support watchdog_core watchdog_dev snd_seq_midi snd_rawmidi snd_seq_midi_event snd_seq rng_core snd_timer snd_seq_device shpchp pci_hotplug battery snd ac button soundcore snd_page_alloc s r_mod cdrom pata_acpi piix ide_core firewire_ohci firewire_core crc_itu_t thermal processor fan [ 54.733915] [ 54.733918] Pid: 5703, comm: tail Not tainted (2.6.24-rc5-mm1 #9) [ 54.733921] EIP: 0060:[] EFLAGS: 00210297 CPU: 1 [ 54.733926] EIP is at r_show+0x2a/0x70 [ 54.733928] EAX: EBX: 0001 ECX: c07e3224 EDX: c04bb034 [ 54.733931] ESI: 0008 EDI: efbe9420 EBP: eed41f10 ESP: eed41f04 [ 54.733934] DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068 [ 54.733938] Process tail (pid: 5703, ti=eed41000 task=ee5a8000 task.ti=eed41000) [ 54.733940] Stack: c03a6cac efbe9420 c07e3224 eed41f50 c0199a7e 2000 097d1f20 e1112500 [ 54.733949]efbe9440 01d3 000e 000d [ 54.733958]fffb f7d79210 c01998e4 eed41f74 c01af4f5 eed41f9c 2000 097d1f20 [ 54.733966] Call Trace: [ 54.733968] [] show_trace_log_lvl+0x12/0x25 [ 54.733975] [] show_stack_log_lvl+0x8a/0x95 [ 54.733980] [] show_registers+0x8c/0x154 [ 54.733984] [] die+0x10e/0x1d2 [ 54.733988] [] do_page_fault+0x52b/0x600 [ 54.733993] [] error_code+0x72/0x78 [ 54.733998] [] seq_read+0x19a/0x26c [ 54.734004] [] proc_reg_read+0x60/0x74 [ 54.734009] [] vfs_read+0xa2/0x11e [ 54.734015] [] sys_read+0x3b/0x60 [ 54.734019] [] sysenter_past_esp+0x6b/0xc1 [ 54.734023] === [ 54.734025] Code: c3 55 89 d1 89 e5 57 89 c7 56 53 8b 50 64 83 7a 0c 00 77 0e 81 7a 08 ff ff 00 00 be 04 00 00 00 76 05 be 08 00 00 00 89 c8 31 db <8b > 40 18 39 d0 74 06 43 83 fb 05 75 f3 8b 41 10 ba 2f 1b 45 c0 [ 54.734071] EIP: [] r_show+0x2a/0x70 SS:ESP 0068:eed41f04 [ 55.363749] BUG: unable to handle kernel NULL pointer dereference at virtual address 0018 [ 55.363756] printing ip: c012d527 *pde = [ 55.363762] Oops: [#2] SMP [ 55.363766] last sysfs file: /sys/devices/pci:00/:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda3/stat [ 55.363770] Modules linked in: aes_i586 aes_generic i915 drm rfcomm l2cap bluetooth acpi_cpufreq cpufreq_stats cpufreq_conservative sbs sbshc dm_crypt sbp2 parport_pc lp parport arc4 ecb crypto_blkcipher cryptomgr crypto_algapi pcmcia snd_hda_intel snd_pcm_oss snd_mixer_oss iwl3945 snd_pcm snd_seq_dumm y mac80211 snd_seq_oss cfg80211 sky2 tifm_7xx1 yenta_socket rsrc_nonstatic pcmcia_core tifm_core iTCO_wdt iTCO_vendor_support watchdog_core watchdog_dev snd_seq_midi snd_rawmidi snd_seq_midi_event snd_seq rng_core snd_timer snd_seq_device shpchp pci_hotplug battery snd ac button soundcore snd_page_alloc s r_mod cdrom pata_acpi piix ide_core firewire_ohci firewire_core crc_itu_t thermal processor fan [ 55.363834] [ 55.363837] Pid: 5710, comm: tail Tainted: G D (2.6.24-rc5-mm1 #9) [ 55.363840] EIP: 0060:[] EFLAGS: 00210297 CPU: 1 [ 55.363845] EIP is at r_show+0x2a/0x70 [ 55.363848] EAX: EBX: 0001 ECX: c07e3224 EDX: c04bb034 [ 55.363851] ESI: 0008 EDI: efbe9420 EBP: ee5a8f10 ESP: ee5a8f04 [ 55.363854] DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068 [ 55.363857] Process tail (pid: 5710, ti=ee5a8000 task=f76ae000 task.ti=ee5a8000) [ 55.363860] Stack: c03a6cac efbe9420 c07e3224 ee5a8f50 c0199a7e 2000 09e26f20 f7036d00 [ 55.363868]efbe9440 01d3 000e 000d [ 55.363877]fffb f7d79210 c01998e4 ee5a8f74 c01af4f5 ee5a8f9c 2000 09e26f20 [ 55.363885] Call Trace: [ 55.363887] [] show_trace_log_lvl+0x12/0x25 [ 55.363894] [] show_stack_log_lvl+0x8a/0x95 [ 55.363898] [] show_registers+0x8c/0x154 [ 55.363902] [] die+0x10e/0x1d2 [ 55.363906] [] do_page_fault+0x52b/0x600 [ 55.363911] [] error_code+0x72/0x78 [ 55.363915] [] seq_read+0x19a/0x26c [ 55.363921] [] proc_reg_read+0x60/0x74 [ 55.363925] [] vfs_read+0xa2/0x11e [ 55.363930] [] sys_read+0x3b/0x60 [ 55.363934] [] sysenter_past_esp+0x6b/0xc1 [ 55.363938] === [ 55.363940] Code: c3
Re: [ia64] BUG: sleeping in atomic
On Wed, Dec 19, 2007 at 11:42:04AM -0500, Kyle McMartin wrote: > On Wed, Dec 19, 2007 at 04:54:30PM +1100, David Chinner wrote: > > [ 5667.086055] BUG: sleeping function called from invalid context at > > kernel/fork.c:401 > > > > The problem is that mmput is called under the read_lock by > find_thread_for_addr... The comment above seems to indicate that gdb > needs to be able to access any child tasks register backing store > memory... This seems pretty broken. > > cheers, Kyle > > --- > > Who knows, maybe gdb is saner now? > > diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c > index 2e96f17..b609704 100644 > --- a/arch/ia64/kernel/ptrace.c > +++ b/arch/ia64/kernel/ptrace.c > @@ -1418,7 +1418,7 @@ asmlinkage long > sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data) > { > struct pt_regs *pt; > - unsigned long urbs_end, peek_or_poke; > + unsigned long urbs_end; > struct task_struct *child; > struct switch_stack *sw; > long ret; > @@ -1430,23 +1430,12 @@ sys_ptrace (long request, pid_t pid, unsigned long > addr, unsigned long data) > goto out; > } > > - peek_or_poke = (request == PTRACE_PEEKTEXT > - || request == PTRACE_PEEKDATA > - || request == PTRACE_POKETEXT > - || request == PTRACE_POKEDATA); > - ret = -ESRCH; > - read_lock(_lock); > - { > - child = find_task_by_pid(pid); > - if (child) { > - if (peek_or_poke) > - child = find_thread_for_addr(child, addr); > - get_task_struct(child); > - } > - } > - read_unlock(_lock); > - if (!child) > + child = ptrace_get_task_struct(pid); > + if (IS_ERR(child)) { > + ret = PTR_ERR(child); > goto out; > + } > + > ret = -EPERM; > if (pid == 1) /* no messing around with init! */ > goto out_tsk; Yes, this patch fixes the problem (though I haven't tried to use gdb yet). Cheers, Dave. -- Dave Chinner Principal Engineer SGI Australian Software Group -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: 2.6.24-rc5-mm1
On Dec 20, 2007 11:34 AM, Alan Stern <[EMAIL PROTECTED]> wrote: > Note carefully. This: > > > > > 2. on 2.6.24-rc5 kernel reports only the part 1, after try mount the > > > > disk it reports the part 2 and mount the partition as rw > > contradicts this: > > > > > 3. on 2.6.24-rc5 kernel reports only the part 1, after try mount the > > > > disk it just mount the partition as ro with nothing more messages. Oh, sorry. It's a typo. should be 2.6.24-rc5-mm1 > > So which is correct? > > > Hi, Alan > > > > I'm sure about my post. > > But your post contradicts itself. It can't be correct. > > > I'm not so famillar with usb. > > It looks weird. Seems that my device will be firstly recoganized as a > > mp3 player and then a usb storage, so the system will report part 1 & > > part 2 under previous kernels. > > I think those "part 2" messages aren't caused by the kernel at all, but > instead by some program running on your computer. You could try > booting into single-user mode and see if the behavior changes. No doubt for me. Under osx plugin this device will popup a dialog(I don't remember the content), after press ok then the disk icon go away, and then being remount again. > > Also there's no question -- the device does behave strangely. It > shouldn't change the write-protect setting all by itself. Yes, I think so too. > > Alan Stern > > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: 2.6.24-rc5-mm1 -- inconsistent {in-hardirq-W} -> {hardirq-on-W} usage -- pm-hibernate/9940 [HC0[0]:SC0[0]:HE1:SE1]
On Dec 19, 2007 8:31 PM, Rafael J. Wysocki <[EMAIL PROTECTED]> wrote: > > On Thursday, 20 of December 2007, Miles Lane wrote: > > On Dec 19, 2007 7:09 PM, Rafael J. Wysocki <[EMAIL PROTECTED]> wrote: > > > > > On Thursday, 20 of December 2007, Christoph Lameter wrote: > > > > On Thu, 20 Dec 2007, Rafael J. Wysocki wrote: > > > > > > > > > > We could reexport drain_local_pages() again but then I do not > > > understand > > > > > > why we would only drain the pages of this processor and not of all > > > other > > > > > > processors as well. It seems that software suspend intend was to > > > flush > > > > > > them all right? > > > > > > > > > > Well, not exactly. We are on one CPU at this point, the others have > > > been > > > > > disabled. > > > > > > > > Ok so the others are flush. Here is a patch to re-export > > > > drain_local_pages() again and use it for software suspend: > > > > > > > > Signed-off-by: Christoph Lameter <[EMAIL PROTECTED]> > > > > > > > > --- > > > > include/linux/gfp.h |1 + > > > > kernel/power/snapshot.c |2 +- > > > > mm/page_alloc.c |2 +- > > > > 3 files changed, 3 insertions(+), 2 deletions(-) > > > > > > > > Index: linux-2.6.24-rc5-mm1/kernel/power/snapshot.c > > > > === > > > > --- linux-2.6.24-rc5-mm1.orig/kernel/power/snapshot.c 2007-12-19 11:59: > > > 25.233961700 -0800 > > > > +++ linux-2.6.24-rc5-mm1/kernel/power/snapshot.c 2007-12-19 15:16: > > > 34.179661929 -0800 > > > > @@ -1203,7 +1203,7 @@ asmlinkage int swsusp_save(void) > > > > > > > > printk(KERN_INFO "PM: Creating hibernation image: \n"); > > > > > > > > - drain_all_pages(); > > > > + drain_local_pages(NULL); > > > > nr_pages = count_data_pages(); > > > > nr_highmem = count_highmem_pages(); > > > > printk(KERN_INFO "PM: Need to copy %u pages\n", nr_pages + > > > nr_highmem); > > > > > > You've omitted the second instance, right before the copy_data_pages() > > > call. > > > > > > > I guess I will wait for a revised patch. > > There's an Andrew's fix on top of this one in -mm: > http://marc.info/?l=linux-mm-commits=119810866812965=2 > > > > > > > Index: linux-2.6.24-rc5-mm1/mm/page_alloc.c > > > > === > > > > --- linux-2.6.24-rc5-mm1.orig/mm/page_alloc.c 2007-12-19 12:01: > > > 00.630421258 -0800 > > > > +++ linux-2.6.24-rc5-mm1/mm/page_alloc.c 2007-12-19 15:12: > > > 19.850545818 -0800 > > > > @@ -930,7 +930,7 @@ static void drain_pages(unsigned int cpu > > > > /* > > > > * Spill all of this CPU's per-cpu pages back into the buddy allocator. > > > > */ > > > > -static void drain_local_pages(void *arg) > > > > +void drain_local_pages(void *arg) > > > > { > > > > drain_pages(smp_processor_id()); > > > > } > > > > Index: linux-2.6.24-rc5-mm1/include/linux/gfp.h > > > > === > > > > --- linux-2.6.24-rc5-mm1.orig/include/linux/gfp.h 2007-12-19 15:13: > > > 51.926950065 -0800 > > > > +++ linux-2.6.24-rc5-mm1/include/linux/gfp.h 2007-12-19 15:16: > > > 11.951564369 -0800 > > > > @@ -229,5 +229,6 @@ extern void FASTCALL(free_cold_page(stru > > > > void page_alloc_init(void); > > > > void drain_zone_pages(struct zone *zone, struct per_cpu_pages *pcp); > > > > void drain_all_pages(void); > > > > +void drain_local_pages(void *dummy); > > > > > > > > #endif /* __LINUX_GFP_H */ > > > > I applied Christoph and Andrew's patches and recompiled. I suspended to disk and to ram several times and all looks good. Miles -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 3/3] pci: Remove pci_enable_device_bars()
Now that all in-tree users are gone, this removes pci_enable_device_bars() completely. Signed-off-by: Benjamin Herrenschmidt <[EMAIL PROTECTED]> --- drivers/pci/pci.c | 24 include/linux/pci.h |1 - 2 files changed, 25 deletions(-) --- linux-work.orig/drivers/pci/pci.c 2007-12-18 11:01:20.0 +1100 +++ linux-work/drivers/pci/pci.c2007-12-18 11:01:28.0 +1100 @@ -713,29 +713,6 @@ int pci_reenable_device(struct pci_dev * return 0; } -/** - * pci_enable_device_bars - Initialize some of a device for use - * @dev: PCI device to be initialized - * @bars: bitmask of BAR's that must be configured - * - * Initialize device before it's used by a driver. Ask low-level code - * to enable selected I/O and memory resources. Wake up the device if it - * was suspended. Beware, this function can fail. - */ -int -pci_enable_device_bars(struct pci_dev *dev, int bars) -{ - int err; - - if (atomic_add_return(1, >enable_cnt) > 1) - return 0; /* already enabled */ - - err = do_pci_enable_device(dev, bars); - if (err < 0) - atomic_dec(>enable_cnt); - return err; -} - static int __pci_enable_device_flags(struct pci_dev *dev, resource_size_t flags) { @@ -1665,7 +1642,6 @@ device_initcall(pci_init); EXPORT_SYMBOL_GPL(pci_restore_bars); EXPORT_SYMBOL(pci_reenable_device); -EXPORT_SYMBOL(pci_enable_device_bars); EXPORT_SYMBOL(pci_enable_device_io); EXPORT_SYMBOL(pci_enable_device_mem); EXPORT_SYMBOL(pci_enable_device); Index: linux-work/include/linux/pci.h === --- linux-work.orig/include/linux/pci.h 2007-12-18 11:00:33.0 +1100 +++ linux-work/include/linux/pci.h 2007-12-18 11:01:28.0 +1100 @@ -547,7 +547,6 @@ static inline int pci_write_config_dword } int __must_check pci_enable_device(struct pci_dev *dev); -int __must_check pci_enable_device_bars(struct pci_dev *dev, int mask); int __must_check pci_enable_device_io(struct pci_dev *dev); int __must_check pci_enable_device_mem(struct pci_dev *dev); int __must_check pci_reenable_device(struct pci_dev *); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 1/3] pci: Add pci_enable_device_{io,mem} intefaces
The pci_enable_device_bars() interface isn't well suited to PCI because you can't actually enable/disable BARs individually on a device. So for example, if a device has 2 memory BARs 0 and 1, and one of them (let's say 1) has not been successfully allocated by the firmware or the kernel, then enabling memory decoding shouldn't be permitted for the entire device since it will decode whatever random address is still in that BAR 1. So a device must be either fully enabled for IO, for Memory, or for both. Not on a per-BAR basis. This provides two new functions, pci_enable_device_io() and pci_enable_device_mem() to replace pci_enable_device_bars(). The implementation internally builds a BAR mask in order to be able to use existing arch infrastructure. Signed-off-by: Benjamin Herrenschmidt <[EMAIL PROTECTED]> --- This (along with the two following patches) is candidate for 2.6.25 Note that I decided not to inline for now in order to keep the existing pci_enable_device() export untouched. I know we have somewhat a policy of screwing up binary drivers but I'd rather not have all nvidia users hate me tomorrow :-) Also, I'm not sure I want to expose pci_enable_device_flags() to drivers anyway. drivers/pci/pci.c | 49 - include/linux/pci.h |2 ++ 2 files changed, 50 insertions(+), 1 deletion(-) --- linux-work.orig/drivers/pci/pci.c 2007-10-15 11:19:38.0 +1000 +++ linux-work/drivers/pci/pci.c2007-12-18 11:01:20.0 +1100 @@ -736,6 +736,51 @@ pci_enable_device_bars(struct pci_dev *d return err; } +static int __pci_enable_device_flags(struct pci_dev *dev, +resource_size_t flags) +{ + int err; + int i, bars = 0; + + if (atomic_add_return(1, >enable_cnt) > 1) + return 0; /* already enabled */ + + for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) + if (dev->resource[i].flags & flags) + bars |= (1 << i); + + err = do_pci_enable_device(dev, bars); + if (err < 0) + atomic_dec(>enable_cnt); + return err; +} + +/** + * pci_enable_device_io - Initialize a device for use with IO space + * @dev: PCI device to be initialized + * + * Initialize device before it's used by a driver. Ask low-level code + * to enable I/O resources. Wake up the device if it was suspended. + * Beware, this function can fail. + */ +int pci_enable_device_io(struct pci_dev *dev) +{ + return __pci_enable_device_flags(dev, IORESOURCE_IO); +} + +/** + * pci_enable_device_mem - Initialize a device for use with Memory space + * @dev: PCI device to be initialized + * + * Initialize device before it's used by a driver. Ask low-level code + * to enable Memory resources. Wake up the device if it was suspended. + * Beware, this function can fail. + */ +int pci_enable_device_mem(struct pci_dev *dev) +{ + return __pci_enable_device_flags(dev, IORESOURCE_MEM); +} + /** * pci_enable_device - Initialize device before it's used by a driver. * @dev: PCI device to be initialized @@ -749,7 +794,7 @@ pci_enable_device_bars(struct pci_dev *d */ int pci_enable_device(struct pci_dev *dev) { - return pci_enable_device_bars(dev, (1 << PCI_NUM_RESOURCES) - 1); + return __pci_enable_device_flags(dev, IORESOURCE_MEM | IORESOURCE_IO); } /* @@ -1621,6 +1666,8 @@ device_initcall(pci_init); EXPORT_SYMBOL_GPL(pci_restore_bars); EXPORT_SYMBOL(pci_reenable_device); EXPORT_SYMBOL(pci_enable_device_bars); +EXPORT_SYMBOL(pci_enable_device_io); +EXPORT_SYMBOL(pci_enable_device_mem); EXPORT_SYMBOL(pci_enable_device); EXPORT_SYMBOL(pcim_enable_device); EXPORT_SYMBOL(pcim_pin_device); Index: linux-work/include/linux/pci.h === --- linux-work.orig/include/linux/pci.h 2007-12-18 11:00:32.0 +1100 +++ linux-work/include/linux/pci.h 2007-12-18 11:00:33.0 +1100 @@ -548,6 +548,8 @@ static inline int pci_write_config_dword int __must_check pci_enable_device(struct pci_dev *dev); int __must_check pci_enable_device_bars(struct pci_dev *dev, int mask); +int __must_check pci_enable_device_io(struct pci_dev *dev); +int __must_check pci_enable_device_mem(struct pci_dev *dev); int __must_check pci_reenable_device(struct pci_dev *); int __must_check pcim_enable_device(struct pci_dev *pdev); void pcim_pin_device(struct pci_dev *pdev); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 2/3] pci: Remove users of pci_enable_device_bars()
This patch converts users of pci_enable_device_bars() to the new pci_enable_device_{io,mem} interface. The new API fits nicely, except maybe for the QLA case where a bit of code re-organization might be a good idea but I prefer sticking to the simple patch as I don't have hardware to test on. I'll also need some feedback on the cs5520 change. Signed-off-by: Benjamin Herrenschmidt <[EMAIL PROTECTED]> --- drivers/ata/pata_cs5520.c |2 +- drivers/i2c/busses/scx200_acb.c |2 +- drivers/ide/pci/cs5520.c| 10 -- drivers/ide/setup-pci.c |6 -- drivers/scsi/lpfc/lpfc_init.c |3 +-- drivers/scsi/qla2xxx/qla_os.c | 12 +--- 6 files changed, 24 insertions(+), 11 deletions(-) --- linux-work.orig/drivers/ata/pata_cs5520.c 2007-12-18 09:37:55.0 +1100 +++ linux-work/drivers/ata/pata_cs5520.c2007-12-18 09:39:03.0 +1100 @@ -229,7 +229,7 @@ static int __devinit cs5520_init_one(str return -ENOMEM; /* Perform set up for DMA */ - if (pci_enable_device_bars(pdev, 1<<2)) { + if (pci_enable_device_io(pdev)) { printk(KERN_ERR DRV_NAME ": unable to configure BAR2.\n"); return -ENODEV; } Index: linux-work/drivers/i2c/busses/scx200_acb.c === --- linux-work.orig/drivers/i2c/busses/scx200_acb.c 2007-12-18 09:37:55.0 +1100 +++ linux-work/drivers/i2c/busses/scx200_acb.c 2007-12-18 09:39:03.0 +1100 @@ -492,7 +492,7 @@ static __init int scx200_create_pci(cons iface->pdev = pdev; iface->bar = bar; - rc = pci_enable_device_bars(iface->pdev, 1 << iface->bar); + rc = pci_enable_device_io(iface->pdev); if (rc) goto errout_free; Index: linux-work/drivers/ide/pci/cs5520.c === --- linux-work.orig/drivers/ide/pci/cs5520.c2007-12-18 09:37:55.0 +1100 +++ linux-work/drivers/ide/pci/cs5520.c 2007-12-18 09:39:03.0 +1100 @@ -160,8 +160,14 @@ static int __devinit cs5520_init_one(str ide_setup_pci_noise(dev, d); /* We must not grab the entire device, it has 'ISA' space in its - BARS too and we will freak out other bits of the kernel */ - if (pci_enable_device_bars(dev, 1<<2)) { +* BARS too and we will freak out other bits of the kernel +* +* pci_enable_device_bars() is going away. I replaced it with +* IO only enable for now but I'll need confirmation this is +* allright for that device. If not, it will need some kind of +* quirk. --BenH. +*/ + if (pci_enable_device_io(dev)) { printk(KERN_WARNING "%s: Unable to enable 55x0.\n", d->name); return -ENODEV; } Index: linux-work/drivers/ide/setup-pci.c === --- linux-work.orig/drivers/ide/setup-pci.c 2007-12-18 09:37:55.0 +1100 +++ linux-work/drivers/ide/setup-pci.c 2007-12-18 09:40:07.0 +1100 @@ -236,7 +236,9 @@ EXPORT_SYMBOL_GPL(ide_setup_pci_noise); * @d: IDE port info * * Enable the IDE PCI device. We attempt to enable the device in full - * but if that fails then we only need BAR4 so we will enable that. + * but if that fails then we only need IO space. The PCI code should + * have setup the proper resources for us already for controllers in + * legacy mode. * * Returns zero on success or an error code */ @@ -246,7 +248,7 @@ static int ide_pci_enable(struct pci_dev int ret; if (pci_enable_device(dev)) { - ret = pci_enable_device_bars(dev, 1 << 4); + ret = pci_enable_device_io(dev); if (ret < 0) { printk(KERN_WARNING "%s: (ide_setup_pci_device:) " "Could not enable device.\n", d->name); Index: linux-work/drivers/scsi/lpfc/lpfc_init.c === --- linux-work.orig/drivers/scsi/lpfc/lpfc_init.c 2007-12-18 09:37:55.0 +1100 +++ linux-work/drivers/scsi/lpfc/lpfc_init.c2007-12-18 09:39:03.0 +1100 @@ -2100,10 +2100,9 @@ static pci_ers_result_t lpfc_io_slot_res struct Scsi_Host *shost = pci_get_drvdata(pdev); struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; struct lpfc_sli *psli = >sli; - int bars = pci_select_bars(pdev, IORESOURCE_MEM); dev_printk(KERN_INFO, >dev, "recovering from a slot reset.\n"); - if (pci_enable_device_bars(pdev, bars)) { + if (pci_enable_device_mem(pdev)) { printk(KERN_ERR "lpfc: Cannot re-enable " "PCI device after reset.\n"); return PCI_ERS_RESULT_DISCONNECT; Index: linux-work/drivers/scsi/qla2xxx/qla_os.c
Re: [RFC] kobject/kset/ktype documentation and example code updated
On Wed, 19 Dec 2007, Greg KH wrote: > Any review comments that people might have on both the document, and the > two sample modules would be greatly appreciated. Here are some things I noticed on a first reading: > Everything you never wanted to know about kobjects, ksets, and ktypes > > Greg Kroah-Hartman <[EMAIL PROTECTED]> > > Based on an original article by Jon Corbet for lwn.net written October 1, > 2003 and located at http://lwn.net/Articles/51437/ > > Last updated December 19, 2007 > > > Part of the difficulty in understanding the driver model - and the kobject > abstraction upon which it is built - is that there is no obvious starting > place. Dealing with kobjects requires understanding a few different types, > all of which make reference to each other. In an attempt to make things > easier, we'll take a multi-pass approach, starting with vague terms and > adding detail as we go. To that end, here are some quick definitions of > some terms we will be working with. > > - A kobject is an object of type struct kobject. Kobjects have a name >and a reference count. A kobject also has a parent pointer (allowing >objects to be arranged into hierarchies), a specific type, and, >usually, a representation in the sysfs virtual filesystem. > >Kobjects are generally not interesting on their own; instead, they are >usually embedded within some other structure which contains the stuff >the code is really interested in. > >No structure should EVER have more than one kobject embedded within it. >If it does, the reference counting for the object is sure to be messed >up and incorrect, and your code will be buggy. So do not do this. > > - A ktype is the type of object that embeds a kobject. Every structure >that embeds a kobject needs a corresponding ktype. The ktype controls I think the wording here is a little misleading. It might be better to say: "For every kind of structure with an embedded kobject, there should be a corresponding ktype object. In each structure of that kind the embedded kobject should contain a pointer to that ktype." Even that isn't great. Maybe somebody can suggest something better. >what happens when a kobject is no longer referenced and the kobject's >default representation in sysfs. > > - A kset is a group of kobjects. These kobjects can be of the same ktype >or belong to different ktypes. The kset is the basic container type for >collections of kobjects. Ksets contain their own kobjects, but you can >safely ignore that implementation detail as the kset core code handles >this kobject automatically. > >When you see a sysfs directory full of other directories, generally each >of those directories corresponds to a kobject in the same kset. > > We'll look at how to create and manipulate all of these types. A bottom-up > approach will be taken, so we'll go back to kobjects. > > > Embedding kobjects > > It is rare for kernel code to create a standalone kobject; with one major The ';' should be a ','. > exception explained below. Instead, kobjects are used to control access to > a larger, domain-specific object. To this end, kobjects will be found > embedded in other structures. If you are used to thinking of things in > object-oriented terms, kobjects can be seen as a top-level, abstract class > from which other classes are derived. A kobject implements a set of > capabilities which are not particularly useful by themselves, but which are > nice to have in other objects. The C language does not allow for the > direct expression of inheritance, so other techniques - such as structure > embedding - must be used. > > So, for example, the UIO code has a structure that defines the memory > region associated with a uio device: > > struct uio_mem { > struct kobject kobj; > unsigned long addr; > unsigned long size; > int memtype; > void __iomem *internal_addr; > }; > > If you have a struct uio_mem structure, finding its embedded kobject is > just a matter of using the kobj structure. Code that works with kobjects "using the kobj member." > will often have the opposite problem, however: given a struct kobject > pointer, what is the pointer to the containing structure? You must avoid > tricks (such as assuming that the kobject is at the beginning of the > structure) and, instead, use the container_of() macro, found in > : > > container_of(pointer, type, member) > > where pointer is the pointer to the embedded kobject, type is the type of > the containing structure, and member is the name of the structure field to > which pointer points. The return value from container_of() is a pointer to > the given type. So, for example, a pointer to a struct kobject embedded > within a struct uio_mem called "kp" could be converted to a pointer to the > containing structure with: > > struct uio_mem *u_mem = container_of(kp, struct uio_mem, kobj); > >
Re: /dev/urandom uses uninit bytes, leaks user data
On Dec 17, 2007 10:46 PM, Theodore Tso <[EMAIL PROTECTED]> wrote: > If you have a system with insufficent entropy inputs, you're in > trouble, of course. There are "catastrophic reseeds" that attempt to > mitigrate some of worse attacks, but at the end of the day, > /dev/random isn't magic. > I understand that there's no way that /dev/random can provide good output if there's insufficient entropy. But it still shouldn't leak arbitrary bits of user data that were never meant to be put into the pool at all. (My hypothetical attack is a lot hypothetical than I thought at first. An attacker does not need to break into the kernel and steal the state of the pool. It may be as easy as this to trigger: Step 1: Boot a system without a usable entropy source. Step 2: add some (predictable) "entropy" from userspace which isn't a multiple of 4, so up to three extra bytes get added. Step 3: Read a few bytes of /dev/random and send them over the network. An attacker can now try all possibilities of the three extra bytes and guess them pretty quickly. No compromise needed. This is, IMHO, bad. (It's one thing for the "random" numbers to be weak. It's another thing entirely for them to reveal data that never belonged in the pool in the first place.) Actually, perhaps there should be a policy that we try never to reseed the pool at all until there is enough entropy around to prevent attacks like these. (In theory the state of the pool might contain 2^(smallish number) bits of data interesting to the attacker even without the uninitialized data issue.) This would make the situation even worse for low-entropy systems, though. --Andy -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: almost daily Kernel oops with 2.6.23.9 - and now 2.6.23.11 as well
On Thu, 2007-12-20 at 03:13 +0100, Hemmann, Volker Armin wrote: > On Montag, 17. Dezember 2007, you wrote: > > and another one, this time tainted with the nvidia module: > 5194.130985] Unable to handle kernel paging request at 0300 RIP: This really sounds like bad hardware. Either memory or the mobo/riser card the memory is on. You might try lowering the memory timings of your memory in BIOS. Try removing 1/2 of your memory. If it still remove the other 1/2 and put the first 1/2 back and try again. -- Scott <[EMAIL PROTECTED]> -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [patch, rfc] mm.h, security.h, key.h and preventing namespace poisoning
On Thu, 20 Dec 2007, David Chinner wrote: > > I'm not sure I understand your namespace pollution issue, either. > > doing this globally: > > #ifdef CONFIG_SOMETHING > extern intsome_common_name(int a, int b, int c); > #else > #define some_common_name(a,b,c) 0 > #endif I suspect it may be useful ensure all global identifiers for the key subsystem are prefixed with key_, as 'copy_keys' does seem a little generic. > > +#ifdef CONFIG_SECURITY > > +extern unsigned long mmap_min_addr; > > +#endif > > + > > #include > > #include > > #include > > Fine by me. I'll queue it for -mm & 2.6.25. - James -- James Morris <[EMAIL PROTECTED]> -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: 2.6.24-rc5-mm1
Note carefully. This: > > > 2. on 2.6.24-rc5 kernel reports only the part 1, after try mount the > > > disk it reports the part 2 and mount the partition as rw contradicts this: > > > 3. on 2.6.24-rc5 kernel reports only the part 1, after try mount the > > > disk it just mount the partition as ro with nothing more messages. So which is correct? > Hi, Alan > > I'm sure about my post. But your post contradicts itself. It can't be correct. > I'm not so famillar with usb. > It looks weird. Seems that my device will be firstly recoganized as a > mp3 player and then a usb storage, so the system will report part 1 & > part 2 under previous kernels. I think those "part 2" messages aren't caused by the kernel at all, but instead by some program running on your computer. You could try booting into single-user mode and see if the behavior changes. Also there's no question -- the device does behave strangely. It shouldn't change the write-protect setting all by itself. Alan Stern -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: almost daily Kernel oops with 2.6.23.9 - and now 2.6.23.11 as well
On Montag, 17. Dezember 2007, you wrote: and another one, this time tainted with the nvidia module: 5194.130985] Unable to handle kernel paging request at 0300 RIP: [ 5194.130988] [] _spin_lock+0x0/0xf [ 5194.130993] PGD 0 [ 5194.130994] Oops: 0002 [1] SMP [ 5194.130996] CPU 1 [ 5194.130997] Modules linked in: rfcomm l2cap hci_usb bluetooth snd_usb_audio ohci1394 snd_usb_lib ieee1394 aic7xxx i2c_nforce2 nvidia(P) k8temp w83627ehf hwmon_vid hwmon i2c_core snd_seq_midi snd_emu10k1_synth snd_emux_synth snd_seq_virmidi snd_seq_midi_emul snd_pcm_oss snd_mixer_oss snd_seq_oss snd_seq_midi_event snd_seq snd_emu10k1 snd_rawmidi snd_ac97_codec ac97_bus snd_pcm snd_seq_device snd_timer snd_page_alloc snd_util_mem snd_hwdep snd r8169 [ 5194.131014] Pid: 22490, comm: sleep Tainted: P2.6.23.11reiser4 #4 [ 5194.131015] RIP: 0010:[] [] _spin_lock+0x0/0xf [ 5194.131018] RSP: 0018:81009278be70 EFLAGS: 00010206 [ 5194.131020] RAX: 2ab90bfb5000 RBX: 810117d44db0 RCX: 2ab90bdb5000 [ 5194.131021] RDX: 81011519f810 RSI: 00388aa08fff RDI: 0300 [ 5194.131023] RBP: 0300 R08: 81012f190ea0 R09: [ 5194.131024] R10: 0008 R11: 0246 R12: 810117d44db0 [ 5194.131026] R13: 2ab90bdb R14: R15: [ 5194.131028] FS: 2ab90bde3070() GS:81012fc6cec0() knlGS:f7f756c0 [ 5194.131030] CS: 0010 DS: ES: CR0: 8005003b [ 5194.131031] CR2: 0300 CR3: 93605000 CR4: 06e0 [ 5194.131033] DR0: DR1: DR2: [ 5194.131034] DR3: DR6: 0ff0 DR7: 0400 [ 5194.131036] Process sleep (pid: 22490, threadinfo 81009278a000, task 8100960630c0) [ 5194.131037] Stack: 8026afbc 810117d44db0 810115e2cbb8 810117d44db0 [ 5194.131040] 80265ec3 81009278bee0 81009278bee0 810115e2c3d8 [ 5194.131043] 8100a076cb80 0002 7fff9ecf7808 7fff9ecf7810 [ 5194.131045] Call Trace: [ 5194.131048] [] anon_vma_unlink+0x1a/0x64 [ 5194.131051] [] free_pgtables+0x64/0xc4 [ 5194.131054] [] exit_mmap+0x91/0xeb [ 5194.131057] [] mmput+0x28/0xa0 [ 5194.131060] [] do_exit+0x211/0x786 [ 5194.131063] [] sys_exit_group+0x0/0xe [ 5194.131065] [] system_call+0x7e/0x83 [ 5194.131069] [ 5194.131070] [ 5194.131070] Code: f0 ff 0f 79 09 f3 90 83 3f 00 7e f9 eb f2 c3 f0 81 2f 00 00 [ 5194.131076] RIP [] _spin_lock+0x0/0xf [ 5194.131078] RSP [ 5194.131079] CR2: 0300 [ 5194.131101] Fixing recursive fault but reboot is needed! -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [lm-sensors] 2.6.24-rc4 hwmon it87 probe fails
On Thursday 20 December 2007 02:13:22 Elvis Pranskevichus wrote: > Hi Carlos, > > I've attached the DSDT for Gigabyte GA-965G-DS3 (rev 1.0, bios rev. F9) to > bugzilla entry #9514: > > http://bugzilla.kernel.org/attachment.cgi?id=14132 A quick look over the DSDT shows that there is no ACPI-WMI mapper device (PNP0C14) on this board; so WMI is, at least in this case, not the solution to this bug. -Carlos -- E-Mail: [EMAIL PROTECTED] Web: strangeworlds.co.uk GPG Key ID: 0x23EE722D -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [lm-sensors] 2.6.24-rc4 hwmon it87 probe fails
On Wednesday December 19 2007 07:45:14 pm Carlos Corbacho wrote: > On Thursday 20 December 2007 00:20:21 Bjorn Helgaas wrote: > > I suspect the manufacturers would say "Oh, the sensors? The BIOS > > isn't broken, you're just supposed to use WMI or some (undocumented) > > ACPI device to get at those." > > It's quite possible - can we have DSDTs for the boards in question so we > can quickly check if this is a possibility? (Basically, to see if they have > PNP0C14 devices - if they don't, then I'm afraid it's nothing to do with > WMI). > > -Carlos Hi Carlos, I've attached the DSDT for Gigabyte GA-965G-DS3 (rev 1.0, bios rev. F9) to bugzilla entry #9514: http://bugzilla.kernel.org/attachment.cgi?id=14132 Thanks, -- Elvis -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] x86: Voluntary leave_mm before entering ACPI C3
On Wed, Dec 19, 2007 at 08:32:55PM +0100, Ingo Molnar wrote: > > * Venki Pallipadi <[EMAIL PROTECTED]> wrote: > > > Aviod TLB flush IPIs during C3 states by voluntary leave_mm() before > > entering C3. > > > > The performance impact of TLB flush on C3 should not be significant > > with respect to C3 wakeup latency. Also, CPUs tend to flush TLB in > > hardware while in C3 anyways. > > > > On a 8 logical CPU system, running make -j2, the number of tlbflush > > IPIs goes down from 40 per second to ~ 0. Total number of interrupts > > during the run of this workload was ~1200 per second, which makes it > > ~3% savings in wakeups. > > > > There was no measurable performance or power impact however. > > thanks, applied to x86.git. Nice and elegant patch! > > Btw., since the TLB flush state machine is really subtle and fragile, > could you try to run the following mmap stresstest i wrote some time > ago: > >http://redhat.com/~mingo/threaded-mmap-stresstest/ > > for a couple of hours. It runs nr_cpus threads which then do a "random > crazy mix" of mappings/unmappings/remappings of a 800 MB memory window. > The more sockets/cores, the crazier the TLB races get ;-) > Ingo, I ran this stress test on two systems (8 cores and 2 cores) for over 4 hours without any issues. There was more than 20% C3 time during the run. So, this C3 tlbflush path must have been stressed well during the run. And sorry about the patch not working on UP config. That was a silly oversight on my part. Thanks, Venki -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: RFC: permit link(2) to work across --bind mounts ?
[EMAIL PROTECTED] wrote: Why does link(2) not support hard-linking across bind mount points of the same underlying filesystem ? Whenever we get mount -r --bind working properly (which I use to place copies of necessary shared libraries inside chroot jails while allowing page cache sharing), this feature would break security. .. No, that would still function exactly as it does today. The alternate behaviour that is desired for non-chroot purposes would be per-bind-mount, and would require a mount flag to activate. Cheers -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [patch 10/20] SEQ replacement for anonymous pages
Hi Rik-san > > > To keep the maximum amount of necessary work reasonable, we scale the > > > active to inactive ratio with the size of memory, using the formula > > > active:inactive ratio = sqrt(memory in GB * 10). > > > why do you think best formula is sqrt(GB*10)? > > please tell me if you don't mind. > > On a 1GB system, this leads to a ratio of 3 active anon > pages to 1 inactive anon page, and a maximum inactive > anon list size of 250MB. > > On a 1TB system, this leads to a ratio of 100 active anon > pages to 1 inactive anon page, and a maximum inactive > anon list size of 10GB. > > The numbers in-between looked reasonable :) thanks for your kind description. I think it make sense. and, please add comment liked blow table if you don't mind. for take more intuitive description. total returnmax memoryvalue inactive anon - 10MB 1 5MB 100MB 150MB 1GB 3 250MB 10GB 10 0.9GB 100GB 31 3GB 1TB 10110GB 10TB 32032GB > Basically the requirement is that the inactive anon list > is large enough that pages get a chance to be referenced > again, but small enough that the maximum amount of work > the VM needs to do is bounded to something reasonable. > > > and i have a bit worry to it works well or not on small systems. > > because it is indicate 1:1 ratio on less than 100MB memory system. > > Do you think this viewpoint? > > A 1:1 ratio simply means that the inactive anon list is > the same size as the active anon list. Page replacement > should still work fine that way. I'm sold. thanks. /kosaki -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [patch, rfc] mm.h, security.h, key.h and preventing namespace poisoning
On Thu, Dec 20, 2007 at 11:07:01AM +1100, James Morris wrote: > On Wed, 19 Dec 2007, David Chinner wrote: > > > Folks, > > > > I just updated a git tree and started getting errors on a > > "copy_keys" macro warning. > > > > The code I've been working on uses a ->copy_keys() method for > > copying the keys in a btree block from one place to another. I've > > been working on this code for a while > > (http://oss.sgi.com/archives/xfs/2007-11/msg00046.html) and keep the > > tree I'm working in reletively up to date (lags linus by a couple of > > weeks at most). The update I did this afternoon gave a conflict > > warning with the macro in include/linux/key.h. > > > > Given that I'm not directly including key.h anywhere in the XFS > > code, I'm getting the namespace polluted indirectly from some other > > include that is necessary. > > > > As it turns out, this commit from 13 days ago: > > > > http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=7cd94146cd504016315608e297219f9fb7b1413b > > > > included security.h in mm.h and that is how I'm seeing the namespace > > poisoning coming from key.h when !CONFIG_KEY. > > > > Including security.h in mm.h means much wider includes for pretty > > much the entire kernel, and it opens up namespace issues like this > > that never previously existed. > > > > The patch below (only tested for !CONFIG_KEYS && !CONFIG_SECURITY) > > moves security.h into the mmap.c and nommu.c files that need it so > > it doesn't end up with kernel wide scope. > > > > Comments? > > The idea with this placement was to keep memory management code with other > similar code, rather than pushing it into security.h, where it does not > functionally belong. > > Something to not also is that you can't "depend" on security.h not being > included all over the place, as LSM does touch a lot of the kernel. > Unecessarily including it is bad, of course. Which is what including it in mm.h does. It also pull sin a lot of other headers files as has already been noted. > I'm not sure I understand your namespace pollution issue, either. doing this globally: #ifdef CONFIG_SOMETHING extern int some_common_name(int a, int b, int c); #else #define some_common_name(a,b,c) 0 #endif means that no-one can use some_common_name *anywhere* in the kernel. In this case, i have a completely *private* use of some_common_name and now I can't use that because the wonderful define above that now has effectively global scope because it gets included from key.h via security.h via mm.h. > In any case, I think the right solution is not to include security.h at > all in mm.h, as it is only being done to get a declaration for > mmap_min_addr. > > How about this, instead ? > > Signed-off-by: James Morris <[EMAIL PROTECTED]> > --- > > mm.h |5 - > 1 file changed, 4 insertions(+), 1 deletion(-) > > diff --git a/include/linux/mm.h b/include/linux/mm.h > index 1b7b95c..02fbac7 100644 > --- a/include/linux/mm.h > +++ b/include/linux/mm.h > @@ -12,7 +12,6 @@ > #include > #include > #include > -#include > > struct mempolicy; > struct anon_vma; > @@ -34,6 +33,10 @@ extern int sysctl_legacy_va_layout; > #define sysctl_legacy_va_layout 0 > #endif > > +#ifdef CONFIG_SECURITY > +extern unsigned long mmap_min_addr; > +#endif > + > #include > #include > #include Fine by me. Cheers, Dave. -- Dave Chinner Principal Engineer SGI Australian Software Group -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 25/63] ide-cd: remove redundant config flags
* Use CDC_* flags directly and remove redundant flags from ->config_flags. While at it: * Add KERN_CONT to printk()-s in ide_cdrom_probe_capabilities(). Signed-off-by: Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]> --- -294 bytes drivers/ide/ide-cd.c | 102 --- drivers/ide/ide-cd.h | 10 - 2 files changed, 40 insertions(+), 72 deletions(-) Index: b/drivers/ide/ide-cd.c === --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -1868,6 +1868,8 @@ cdrom_lockdoor(ide_drive_t *drive, int l static int cdrom_eject(ide_drive_t *drive, int ejectflag, struct request_sense *sense) { + struct cdrom_info *cd = drive->driver_data; + struct cdrom_device_info *cdi = >devinfo; struct request req; char loej = 0x02; @@ -1881,7 +1883,7 @@ static int cdrom_eject(ide_drive_t *driv cdrom_prepare_request(drive, ); /* only tell drive to close tray if open, if it can do that */ - if (ejectflag && !CDROM_CONFIG_FLAGS(drive)->close_tray) + if (ejectflag && (cdi->mask & CDC_CLOSE_TRAY)) loej = 0; req.sense = sense; @@ -2142,6 +2144,8 @@ static int cdrom_read_subchannel(ide_dri static int cdrom_select_speed(ide_drive_t *drive, int speed, struct request_sense *sense) { + struct cdrom_info *cd = drive->driver_data; + struct cdrom_device_info *cdi = >devinfo; struct request req; cdrom_prepare_request(drive, ); @@ -2156,9 +2160,8 @@ static int cdrom_select_speed(ide_drive_ req.cmd[2] = (speed >> 8) & 0xff; /* Read Drive speed in kbytes/second LSB */ req.cmd[3] = speed & 0xff; - if (CDROM_CONFIG_FLAGS(drive)->cd_r || - CDROM_CONFIG_FLAGS(drive)->cd_rw || - CDROM_CONFIG_FLAGS(drive)->dvd_r) { + if ((cdi->mask & (CDC_CD_R | CDC_CD_RW | CDC_DVD_R)) != + (CDC_CD_R | CDC_CD_RW | CDC_DVD_R)) { /* Write Drive speed in kbytes/second MSB */ req.cmd[4] = (speed >> 8) & 0xff; /* Write Drive speed in kbytes/second LSB */ @@ -2588,33 +2591,10 @@ static int ide_cdrom_register (ide_drive struct cdrom_device_info *devinfo = >devinfo; devinfo->ops = _cdrom_dops; - devinfo->mask = 0; devinfo->speed = CDROM_STATE_FLAGS(drive)->current_speed; devinfo->capacity = nslots; devinfo->handle = drive; strcpy(devinfo->name, drive->name); - - /* set capability mask to match the probe. */ - if (!CDROM_CONFIG_FLAGS(drive)->cd_r) - devinfo->mask |= CDC_CD_R; - if (!CDROM_CONFIG_FLAGS(drive)->cd_rw) - devinfo->mask |= CDC_CD_RW; - if (!CDROM_CONFIG_FLAGS(drive)->dvd) - devinfo->mask |= CDC_DVD; - if (!CDROM_CONFIG_FLAGS(drive)->dvd_r) - devinfo->mask |= CDC_DVD_R; - if (!CDROM_CONFIG_FLAGS(drive)->dvd_ram) - devinfo->mask |= CDC_DVD_RAM; - if (!CDROM_CONFIG_FLAGS(drive)->is_changer) - devinfo->mask |= CDC_SELECT_DISC; - if (!CDROM_CONFIG_FLAGS(drive)->audio_play) - devinfo->mask |= CDC_PLAY_AUDIO; - if (!CDROM_CONFIG_FLAGS(drive)->close_tray) - devinfo->mask |= CDC_CLOSE_TRAY; - if (!CDROM_CONFIG_FLAGS(drive)->mo_drive) - devinfo->mask |= CDC_MO_DRIVE; - if (!CDROM_CONFIG_FLAGS(drive)->ram) - devinfo->mask |= CDC_RAM; if (CDROM_CONFIG_FLAGS(drive)->no_speed_select) devinfo->mask |= CDC_SELECT_SPEED; @@ -2631,9 +2611,12 @@ int ide_cdrom_probe_capabilities (ide_dr struct atapi_capabilities_page cap; int nslots = 1; + cdi->mask = (CDC_CD_R | CDC_CD_RW | CDC_DVD | CDC_DVD_R | +CDC_DVD_RAM | CDC_SELECT_DISC | CDC_PLAY_AUDIO | +CDC_MO_DRIVE | CDC_RAM); + if (drive->media == ide_optical) { - CDROM_CONFIG_FLAGS(drive)->mo_drive = 1; - CDROM_CONFIG_FLAGS(drive)->ram = 1; + cdi->mask &= ~(CDC_MO_DRIVE | CDC_RAM); printk(KERN_ERR "%s: ATAPI magneto-optical drive\n", drive->name); return nslots; } @@ -2641,7 +2624,7 @@ int ide_cdrom_probe_capabilities (ide_dr if (CDROM_CONFIG_FLAGS(drive)->nec260 || !strcmp(drive->id->model,"STINGRAY 8422 IDE 8X CD-ROM 7-27-95")) { CDROM_CONFIG_FLAGS(drive)->no_eject = 0; - CDROM_CONFIG_FLAGS(drive)->audio_play = 1; + cdi->mask &= ~CDC_PLAY_AUDIO; return nslots; } @@ -2663,23 +2646,19 @@ int ide_cdrom_probe_capabilities (ide_dr if (cap.eject) CDROM_CONFIG_FLAGS(drive)->no_eject = 0; if (cap.cd_r_write) - CDROM_CONFIG_FLAGS(drive)->cd_r = 1; - if
[PATCH 24/63] ide-cd: add IDE_CD_CAPABILITIES define
While at it remove stale/incorrect comment. Signed-off-by: Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]> --- drivers/ide/ide-cd.c | 19 +++ 1 file changed, 7 insertions(+), 12 deletions(-) Index: b/drivers/ide/ide-cd.c === --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -2559,11 +2559,13 @@ void ide_cdrom_release_real (struct cdro CDROM_STATE_FLAGS(drive)->toc_valid = 0; } +#define IDE_CD_CAPABILITIES \ + (CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK | CDC_SELECT_SPEED | \ +CDC_SELECT_DISC | CDC_MULTI_SESSION | CDC_MCN | CDC_MEDIA_CHANGED | \ +CDC_PLAY_AUDIO | CDC_RESET | CDC_DRIVE_STATUS | CDC_CD_R | \ +CDC_CD_RW | CDC_DVD | CDC_DVD_R | CDC_DVD_RAM | CDC_GENERIC_PACKET | \ +CDC_MO_DRIVE | CDC_MRW | CDC_MRW_W | CDC_RAM) - -/ - * Device initialization. - */ static struct cdrom_device_ops ide_cdrom_dops = { .open = ide_cdrom_open_real, .release= ide_cdrom_release_real, @@ -2576,14 +2578,7 @@ static struct cdrom_device_ops ide_cdrom .get_mcn= ide_cdrom_get_mcn, .reset = ide_cdrom_reset, .audio_ioctl= ide_cdrom_audio_ioctl, - .capability = CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK | - CDC_SELECT_SPEED | CDC_SELECT_DISC | - CDC_MULTI_SESSION | CDC_MCN | - CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO | CDC_RESET | - CDC_DRIVE_STATUS | CDC_CD_R | - CDC_CD_RW | CDC_DVD | CDC_DVD_R| CDC_DVD_RAM | - CDC_GENERIC_PACKET | CDC_MO_DRIVE | CDC_MRW | - CDC_MRW_W | CDC_RAM, + .capability = IDE_CD_CAPABILITIES, .generic_packet = ide_cdrom_packet, }; -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 23/63] ide-cd: cleanup ide_cdrom_update_speed()
Signed-off-by: Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]> --- -39 bytes drivers/ide/ide-cd.c | 17 + 1 file changed, 9 insertions(+), 8 deletions(-) Index: b/drivers/ide/ide-cd.c === --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -2395,19 +2395,20 @@ int ide_cdrom_get_capabilities(ide_drive static void ide_cdrom_update_speed (ide_drive_t *drive, struct atapi_capabilities_page *cap) { + u16 curspeed, maxspeed; + /* The ACER/AOpen 24X cdrom has the speed fields byte-swapped */ if (!drive->id->model[0] && !strncmp(drive->id->fw_rev, "241N", 4)) { - CDROM_STATE_FLAGS(drive)->current_speed = - (le16_to_cpu(cap->curspeed) + (176/2)) / 176; - CDROM_CONFIG_FLAGS(drive)->max_speed = - (le16_to_cpu(cap->maxspeed) + (176/2)) / 176; + curspeed = le16_to_cpu(cap->curspeed); + maxspeed = le16_to_cpu(cap->maxspeed); } else { - CDROM_STATE_FLAGS(drive)->current_speed = - (be16_to_cpu(cap->curspeed) + (176/2)) / 176; - CDROM_CONFIG_FLAGS(drive)->max_speed = - (be16_to_cpu(cap->maxspeed) + (176/2)) / 176; + curspeed = be16_to_cpu(cap->curspeed); + maxspeed = be16_to_cpu(cap->maxspeed); } + + CDROM_STATE_FLAGS(drive)->current_speed = (curspeed + (176/2)) / 176; + CDROM_CONFIG_FLAGS(drive)->max_speed = (maxspeed + (176/2)) / 176; } static -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 27/63] ide-cd: kill CDROM_STATE_FLAGS() macro
While at it rename 'info' variable to 'cd' in cdrom_saw_media_change(). Signed-off-by: Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]> --- -49 bytes drivers/ide/ide-cd.c | 44 drivers/ide/ide-cd.h |2 -- 2 files changed, 24 insertions(+), 22 deletions(-) Index: b/drivers/ide/ide-cd.c === --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -93,11 +93,11 @@ static void ide_cd_put(struct cdrom_info buffers. */ static void cdrom_saw_media_change (ide_drive_t *drive) { - struct cdrom_info *info = drive->driver_data; - - CDROM_STATE_FLAGS (drive)->media_changed = 1; - CDROM_STATE_FLAGS (drive)->toc_valid = 0; - info->nsectors_buffered = 0; + struct cdrom_info *cd = drive->driver_data; + + cd->state_flags.media_changed = 1; + cd->state_flags.toc_valid = 0; + cd->nsectors_buffered = 0; } static int cdrom_log_sense(ide_drive_t *drive, struct request *rq, @@ -1859,7 +1859,7 @@ cdrom_lockdoor(ide_drive_t *drive, int l stat = 0; if (stat == 0) - CDROM_STATE_FLAGS(drive)->door_locked = lockflag; + cd->state_flags.door_locked = lockflag; return stat; } @@ -1879,7 +1879,7 @@ static int cdrom_eject(ide_drive_t *driv return -EDRIVE_CANT_DO_THIS; /* reload fails on some drives, if the tray is locked */ - if (CDROM_STATE_FLAGS(drive)->door_locked && ejectflag) + if (cd->state_flags.door_locked && ejectflag) return 0; cdrom_prepare_request(drive, ); @@ -1977,7 +1977,7 @@ static int cdrom_read_toc(ide_drive_t *d If it is, just return. */ (void) cdrom_check_status(drive, sense); - if (CDROM_STATE_FLAGS(drive)->toc_valid) + if (info->state_flags.toc_valid) return 0; /* Try to get the total cdrom capacity and sector size. */ @@ -2116,7 +2116,7 @@ static int cdrom_read_toc(ide_drive_t *d } /* Remember that we've read this stuff. */ - CDROM_STATE_FLAGS(drive)->toc_valid = 1; + info->state_flags.toc_valid = 1; return 0; } @@ -2198,7 +2198,7 @@ static int cdrom_get_toc_entry(ide_drive /* * don't serve cached data, if the toc isn't valid */ - if (!CDROM_STATE_FLAGS(drive)->toc_valid) + if (!info->state_flags.toc_valid) return -EINVAL; /* Check validity of requested track number. */ @@ -2330,6 +2330,7 @@ static int ide_cdrom_reset (struct cdrom_device_info *cdi) { ide_drive_t *drive = cdi->handle; + struct cdrom_info *cd = drive->driver_data; struct request_sense sense; struct request req; int ret; @@ -2343,7 +2344,7 @@ int ide_cdrom_reset (struct cdrom_device * A reset will unlock the door. If it was previously locked, * lock it again. */ - if (CDROM_STATE_FLAGS(drive)->door_locked) + if (cd->state_flags.door_locked) (void) cdrom_lockdoor(drive, 1, ); return ret; @@ -2413,7 +2414,7 @@ void ide_cdrom_update_speed (ide_drive_t maxspeed = be16_to_cpu(cap->maxspeed); } - CDROM_STATE_FLAGS(drive)->current_speed = (curspeed + (176/2)) / 176; + cd->state_flags.current_speed = (curspeed + (176/2)) / 176; cd->config_flags.max_speed = (maxspeed + (176/2)) / 176; } @@ -2421,6 +2422,7 @@ static int ide_cdrom_select_speed (struct cdrom_device_info *cdi, int speed) { ide_drive_t *drive = cdi->handle; + struct cdrom_info *cd = drive->driver_data; struct request_sense sense; struct atapi_capabilities_page cap; int stat; @@ -2430,7 +2432,7 @@ int ide_cdrom_select_speed (struct cdrom if (!ide_cdrom_get_capabilities(drive, )) { ide_cdrom_update_speed(drive, ); - cdi->speed = CDROM_STATE_FLAGS(drive)->current_speed; + cdi->speed = cd->state_flags.current_speed; } return 0; } @@ -2491,7 +2493,7 @@ int ide_cdrom_get_last_session (struct c struct request_sense sense; int ret; - if (!CDROM_STATE_FLAGS(drive)->toc_valid || info->toc == NULL) + if (!info->state_flags.toc_valid || info->toc == NULL) if ((ret = cdrom_read_toc(drive, ))) return ret; @@ -2533,12 +2535,13 @@ int ide_cdrom_check_media_change_real (s int slot_nr) { ide_drive_t *drive = cdi->handle; + struct cdrom_info *cd = drive->driver_data; int retval; - + if (slot_nr == CDSL_CURRENT) { (void) cdrom_check_status(drive, NULL); - retval = CDROM_STATE_FLAGS(drive)->media_changed; - CDROM_STATE_FLAGS(drive)->media_changed = 0; + retval =
[PATCH 03/63] ide-cd: use ide_cd_release() in ide_cd_probe()
Use ide_cd_release() to do the cleanup if ide_cdrom_setup() fails. It fixes: - the default drive->dsc_overlap value not being restored - the default drive->queue's prep_rq_fn not being restored - struct gendisk 'g' not being freed - wrong function name being reported on unregister_cdrom() error Signed-off-by: Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]> --- -164 bytes drivers/ide/ide-cd.c |9 + 1 file changed, 1 insertion(+), 8 deletions(-) Index: b/drivers/ide/ide-cd.c === --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -3501,15 +3501,8 @@ static int ide_cd_probe(ide_drive_t *dri g->driverfs_dev = >gendev; g->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE; if (ide_cdrom_setup(drive)) { - struct cdrom_device_info *devinfo = >devinfo; ide_proc_unregister_driver(drive, _cdrom_driver); - kfree(info->buffer); - kfree(info->toc); - kfree(info->changer_info); - if (devinfo->handle == drive && unregister_cdrom(devinfo)) - printk (KERN_ERR "%s: ide_cdrom_cleanup failed to unregister device from the cdrom driver.\n", drive->name); - kfree(info); - drive->driver_data = NULL; + ide_cd_release(>kref); goto failed; } -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 29/63] ide-cd: remove struct ide_cd_{config,state}_flags
* Remove unused ->{writing,reserved} fields from struct ide_cd_config_flags. * Move ->max_speed from struct ide_cd_config_flags to struct cdrom_info. * Move ->current_speed from struct ide_cd_state_flags to struct cdrom_info. * Add defines for config and state flags. * Add 'unsigned int cd_flags' to struct cdrom_info and use ->cd_flags instead of ->{config,state}_flags. * Remove no longer needed struct ide_cd_{config,state}_flags. Signed-off-by: Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]> --- -45 bytes drivers/ide/ide-cd.c | 106 ++- drivers/ide/ide-cd.h | 62 +++-- 2 files changed, 87 insertions(+), 81 deletions(-) Index: b/drivers/ide/ide-cd.c === --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -95,8 +95,8 @@ static void cdrom_saw_media_change (ide_ { struct cdrom_info *cd = drive->driver_data; - cd->state_flags.media_changed = 1; - cd->state_flags.toc_valid = 0; + cd->cd_flags |= IDE_CD_FLAG_MEDIA_CHANGED; + cd->cd_flags &= ~IDE_CD_FLAG_TOC_VALID; cd->nsectors_buffered = 0; } @@ -658,7 +658,7 @@ static ide_startstop_t cdrom_start_packe ide_pktcmd_tf_load(drive, IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL | IDE_TFLAG_NO_SELECT_MASK, xferlen, info->dma); - if (info->config_flags.drq_interrupt) { + if (info->cd_flags & IDE_CD_FLAG_DRQ_INTERRUPT) { /* waiting for CDB interrupt, not DMA yet. */ if (info->dma) drive->waiting_for_dma = 0; @@ -694,7 +694,7 @@ static ide_startstop_t cdrom_transfer_pa struct cdrom_info *info = drive->driver_data; ide_startstop_t startstop; - if (info->config_flags.drq_interrupt) { + if (info->cd_flags & IDE_CD_FLAG_DRQ_INTERRUPT) { /* Here we should have been called after receiving an interrupt from the device. DRQ should how be set. */ @@ -893,11 +893,11 @@ static ide_startstop_t cdrom_read_intr ( if ((len % SECTOR_SIZE) != 0) { printk (KERN_ERR "%s: cdrom_read_intr: Bad transfer size %d\n", drive->name, len); - if (info->config_flags.limit_nframes) + if (info->cd_flags & IDE_CD_FLAG_LIMIT_NFRAMES) printk (KERN_ERR " This drive is not supported by this version of the driver\n"); else { printk (KERN_ERR " Trying to limit transfer sizes\n"); - info->config_flags.limit_nframes = 1; + info->cd_flags |= IDE_CD_FLAG_LIMIT_NFRAMES; } cdrom_end_request(drive, 0); return ide_stopped; @@ -1074,7 +1074,7 @@ static ide_startstop_t cdrom_seek_intr ( if (cdrom_decode_status(drive, 0, )) return ide_stopped; - info->config_flags.seeking = 1; + info->cd_flags |= IDE_CD_FLAG_SEEKING; if (retry && time_after(jiffies, info->start_seek + IDECD_SEEK_TIMER)) { if (--retry == 0) { @@ -1701,7 +1701,7 @@ ide_do_rw_cdrom (ide_drive_t *drive, str struct cdrom_info *info = drive->driver_data; if (blk_fs_request(rq)) { - if (info->config_flags.seeking) { + if (info->cd_flags & IDE_CD_FLAG_SEEKING) { unsigned long elapsed = jiffies - info->start_seek; int stat = HWIF(drive)->INB(IDE_STATUS_REG); @@ -1712,7 +1712,7 @@ ide_do_rw_cdrom (ide_drive_t *drive, str } printk (KERN_ERR "%s: DSC timeout\n", drive->name); } - info->config_flags.seeking = 0; + info->cd_flags &= ~IDE_CD_FLAG_SEEKING; } if ((rq_data_dir(rq) == READ) && IDE_LARGE_SEEK(info->last_block, block, IDECD_SEEK_THRESHOLD) && drive->dsc_overlap) { action = cdrom_start_seek(drive, block); @@ -1833,7 +1833,7 @@ cdrom_lockdoor(ide_drive_t *drive, int l sense = _sense; /* If the drive cannot lock the door, just pretend. */ - if (cd->config_flags.no_doorlock) { + if (cd->cd_flags & IDE_CD_FLAG_NO_DOORLOCK) { stat = 0; } else { cdrom_prepare_request(drive, ); @@ -1850,7 +1850,7 @@ cdrom_lockdoor(ide_drive_t *drive, int l (sense->asc == 0x24 || sense->asc == 0x20)) { printk (KERN_ERR "%s: door locking not supported\n", drive->name); - cd->config_flags.no_doorlock = 1; + cd->cd_flags |= IDE_CD_FLAG_NO_DOORLOCK; stat = 0; } @@ -1858,8 +1858,12 @@ cdrom_lockdoor(ide_drive_t *drive, int l if (stat != 0 &&
[PATCH 28/63] ide-cd: remove struct atapi_capabilities_page
* Remove struct atapi_capabilities_page. * Add ATAPI_CAPABILITIES_PAGE[_PAD]_SIZE define. Signed-off-by: Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]> --- drivers/ide/ide-cd.c | 62 +++--- drivers/ide/ide-cd.h | 223 --- 2 files changed, 37 insertions(+), 248 deletions(-) Index: b/drivers/ide/ide-cd.c === --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -2373,13 +2373,12 @@ int ide_cdrom_lock_door (struct cdrom_de return cdrom_lockdoor(drive, lock, NULL); } -static -int ide_cdrom_get_capabilities(ide_drive_t *drive, struct atapi_capabilities_page *cap) +static int ide_cdrom_get_capabilities(ide_drive_t *drive, u8 *buf) { struct cdrom_info *info = drive->driver_data; struct cdrom_device_info *cdi = >devinfo; struct packet_command cgc; - int stat, attempts = 3, size = sizeof(*cap); + int stat, attempts = 3, size = ATAPI_CAPABILITIES_PAGE_SIZE; /* * ACER50 (and others?) require the full spec length mode sense @@ -2387,9 +2386,9 @@ int ide_cdrom_get_capabilities(ide_drive */ if (!(!strcmp(drive->id->model, "ATAPI CD ROM DRIVE 50X MAX") || !strcmp(drive->id->model, "WPI CDS-32X"))) - size -= sizeof(cap->pad); + size -= ATAPI_CAPABILITIES_PAGE_PAD_SIZE; - init_cdrom_command(, cap, size, CGC_DATA_UNKNOWN); + init_cdrom_command(, buf, size, CGC_DATA_UNKNOWN); do { /* we seem to get stat=0x01,err=0x00 the first time (??) */ stat = cdrom_mode_sense(cdi, , GPMODE_CAPABILITIES_PAGE, 0); if (!stat) @@ -2398,20 +2397,22 @@ int ide_cdrom_get_capabilities(ide_drive return stat; } -static -void ide_cdrom_update_speed (ide_drive_t *drive, struct atapi_capabilities_page *cap) +static void ide_cdrom_update_speed(ide_drive_t *drive, u8 *buf) { struct cdrom_info *cd = drive->driver_data; u16 curspeed, maxspeed; + curspeed = *(u16 *)[8 + 8]; + maxspeed = *(u16 *)[8 + 14]; + /* The ACER/AOpen 24X cdrom has the speed fields byte-swapped */ if (!drive->id->model[0] && !strncmp(drive->id->fw_rev, "241N", 4)) { - curspeed = le16_to_cpu(cap->curspeed); - maxspeed = le16_to_cpu(cap->maxspeed); + curspeed = le16_to_cpu(curspeed); + maxspeed = le16_to_cpu(maxspeed); } else { - curspeed = be16_to_cpu(cap->curspeed); - maxspeed = be16_to_cpu(cap->maxspeed); + curspeed = be16_to_cpu(curspeed); + maxspeed = be16_to_cpu(maxspeed); } cd->state_flags.current_speed = (curspeed + (176/2)) / 176; @@ -2424,14 +2425,14 @@ int ide_cdrom_select_speed (struct cdrom ide_drive_t *drive = cdi->handle; struct cdrom_info *cd = drive->driver_data; struct request_sense sense; - struct atapi_capabilities_page cap; + u8 buf[ATAPI_CAPABILITIES_PAGE_SIZE]; int stat; if ((stat = cdrom_select_speed(drive, speed, )) < 0) return stat; - if (!ide_cdrom_get_capabilities(drive, )) { - ide_cdrom_update_speed(drive, ); + if (!ide_cdrom_get_capabilities(drive, buf)) { + ide_cdrom_update_speed(drive, buf); cdi->speed = cd->state_flags.current_speed; } return 0; @@ -2615,7 +2616,8 @@ int ide_cdrom_probe_capabilities (ide_dr { struct cdrom_info *cd = drive->driver_data; struct cdrom_device_info *cdi = >devinfo; - struct atapi_capabilities_page cap; + u8 buf[ATAPI_CAPABILITIES_PAGE_SIZE]; + mechtype_t mechtype; int nslots = 1; cdi->mask = (CDC_CD_R | CDC_CD_RW | CDC_DVD | CDC_DVD_R | @@ -2645,26 +2647,28 @@ int ide_cdrom_probe_capabilities (ide_dr cdi->handle = drive; cdi->ops = _cdrom_dops; - if (ide_cdrom_get_capabilities(drive, )) + if (ide_cdrom_get_capabilities(drive, buf)) return 0; - if (cap.lock == 0) + if ((buf[8 + 6] & 0x01) == 0) cd->config_flags.no_doorlock = 1; - if (cap.eject) + if (buf[8 + 6] & 0x08) cd->config_flags.no_eject = 0; - if (cap.cd_r_write) + if (buf[8 + 3] & 0x01) cdi->mask &= ~CDC_CD_R; - if (cap.cd_rw_write) + if (buf[8 + 3] & 0x02) cdi->mask &= ~(CDC_CD_RW | CDC_RAM); - if (cap.dvd_ram_read || cap.dvd_r_read || cap.dvd_rom) + if (buf[8 + 2] & 0x38) cdi->mask &= ~CDC_DVD; - if (cap.dvd_ram_write) + if (buf[8 + 3] & 0x20) cdi->mask &= ~(CDC_DVD_RAM | CDC_RAM); - if (cap.dvd_r_write) + if (buf[8 + 3] & 0x10) cdi->mask &= ~CDC_DVD_R; - if (cap.audio_play) + if (buf[8 + 4] & 0x01)
[PATCH 30/63] ide-cd: remove NO_DOOR_LOCKING define
Signed-off-by: Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]> --- drivers/ide/ide-cd.c |3 --- drivers/ide/ide-cd.h |7 --- 2 files changed, 10 deletions(-) Index: b/drivers/ide/ide-cd.c === --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -2834,9 +2834,6 @@ int ide_cdrom_setup (ide_drive_t *drive) cd->cd_flags |= IDE_CD_FLAG_MEDIA_CHANGED; -#if NO_DOOR_LOCKING - cd->cd_flags |= IDE_CD_FLAG_NO_DOORLOCK; -#endif if ((drive->id->config & 0x0060) == 0x20) cd->cd_flags |= IDE_CD_FLAG_DRQ_INTERRUPT; cd->cd_flags |= IDE_CD_FLAG_NO_EJECT; Index: b/drivers/ide/ide-cd.h === --- a/drivers/ide/ide-cd.h +++ b/drivers/ide/ide-cd.h @@ -28,13 +28,6 @@ #endif -/* Turning this on will disable the door-locking functionality. - This is apparently needed for supermount. */ - -#ifndef NO_DOOR_LOCKING -#define NO_DOOR_LOCKING 0 -#endif - /* * typical timeout for packet command */ -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 05/63] ide-cd: add missing 'ireason' masking to cdrom_write_intr()
Mask 'ireason' variable with 0x3 so the valid interrupt reason value is passed to cdrom_write_check_ireason() for checking. Signed-off-by: Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]> --- drivers/ide/ide-cd.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) Index: b/drivers/ide/ide-cd.c === --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -1820,7 +1820,7 @@ static ide_startstop_t cdrom_write_intr( } /* Read the interrupt reason and the transfer length. */ - ireason = HWIF(drive)->INB(IDE_IREASON_REG); + ireason = HWIF(drive)->INB(IDE_IREASON_REG) & 0x3; lowcyl = HWIF(drive)->INB(IDE_BCOUNTL_REG); highcyl = HWIF(drive)->INB(IDE_BCOUNTH_REG); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 31/63] ide-cd: remove STANDARD_ATAPI define
Remove STANDARD_ATAPI define + drive-by coding style fixes. Signed-off-by: Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]> --- drivers/ide/ide-cd.c | 43 ++- drivers/ide/ide-cd.h | 10 -- 2 files changed, 10 insertions(+), 43 deletions(-) Index: b/drivers/ide/ide-cd.c === --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -1754,7 +1754,6 @@ ide_do_rw_cdrom (ide_drive_t *drive, str * can also be NULL, in which case no sense information is returned. */ -#if ! STANDARD_ATAPI static inline int bin2bcd (int x) { @@ -1776,9 +1775,6 @@ void msf_from_bcd (struct atapi_msf *msf msf->frame = bcd2bin (msf->frame); } -#endif /* not STANDARD_ATAPI */ - - static inline void lba_to_msf (int lba, byte *m, byte *s, byte *f) { @@ -1809,12 +1805,11 @@ static int cdrom_check_status(ide_drive_ req.cmd[0] = GPCMD_TEST_UNIT_READY; req.cmd_flags |= REQ_QUIET; -#if ! STANDARD_ATAPI -/* the Sanyo 3 CD changer uses byte 7 of TEST_UNIT_READY to - switch CDs instead of supporting the LOAD_UNLOAD opcode */ - + /* +* Sanyo 3 CD changer uses byte 7 of TEST_UNIT_READY to +* switch CDs instead of supporting the LOAD_UNLOAD opcode. +*/ req.cmd[7] = cdi->sanyo_slot % 3; -#endif /* not STANDARD_ATAPI */ return cdrom_queue_packet_command(drive, ); } @@ -2003,12 +1998,10 @@ static int cdrom_read_toc(ide_drive_t *d if (stat) return stat; -#if ! STANDARD_ATAPI if (info->cd_flags & IDE_CD_FLAG_TOCTRACKS_AS_BCD) { toc->hdr.first_track = bcd2bin(toc->hdr.first_track); toc->hdr.last_track = bcd2bin(toc->hdr.last_track); } -#endif /* not STANDARD_ATAPI */ ntracks = toc->hdr.last_track - toc->hdr.first_track + 1; if (ntracks <= 0) @@ -2040,16 +2033,13 @@ static int cdrom_read_toc(ide_drive_t *d (ntracks + 1) * sizeof(struct atapi_toc_entry), sense); - if (stat) { + if (stat) return stat; - } -#if ! STANDARD_ATAPI + if (info->cd_flags & IDE_CD_FLAG_TOCTRACKS_AS_BCD) { toc->hdr.first_track = bin2bcd(CDROM_LEADOUT); toc->hdr.last_track = bin2bcd(CDROM_LEADOUT); - } else -#endif /* not STANDARD_ATAPI */ - { + } else { toc->hdr.first_track = CDROM_LEADOUT; toc->hdr.last_track = CDROM_LEADOUT; } @@ -2060,21 +2050,17 @@ static int cdrom_read_toc(ide_drive_t *d toc->hdr.toc_length = ntohs (toc->hdr.toc_length); -#if ! STANDARD_ATAPI if (info->cd_flags & IDE_CD_FLAG_TOCTRACKS_AS_BCD) { toc->hdr.first_track = bcd2bin(toc->hdr.first_track); toc->hdr.last_track = bcd2bin(toc->hdr.last_track); } -#endif /* not STANDARD_ATAPI */ - for (i=0; i<=ntracks; i++) { -#if ! STANDARD_ATAPI + for (i = 0; i <= ntracks; i++) { if (info->cd_flags & IDE_CD_FLAG_TOCADDR_AS_BCD) { if (info->cd_flags & IDE_CD_FLAG_TOCTRACKS_AS_BCD) toc->ent[i].track = bcd2bin(toc->ent[i].track); msf_from_bcd(>ent[i].addr.msf); } -#endif /* not STANDARD_ATAPI */ toc->ent[i].addr.lba = msf_to_lba (toc->ent[i].addr.msf.minute, toc->ent[i].addr.msf.second, toc->ent[i].addr.msf.frame); @@ -2094,7 +2080,6 @@ static int cdrom_read_toc(ide_drive_t *d toc->last_session_lba = msf_to_lba(0, 2, 0); /* 0m 2s 0f */ } -#if ! STANDARD_ATAPI if (info->cd_flags & IDE_CD_FLAG_TOCADDR_AS_BCD) { /* Re-read multisession information using MSF format */ stat = cdrom_read_tocentry(drive, 0, 1, 1, (char *)_tmp, @@ -2107,7 +2092,6 @@ static int cdrom_read_toc(ide_drive_t *d ms_tmp.ent.addr.msf.second, ms_tmp.ent.addr.msf.frame); } -#endif /* not STANDARD_ATAPI */ toc->xa_flag = (ms_tmp.hdr.first_track != ms_tmp.hdr.last_track); @@ -2684,16 +2668,11 @@ int ide_cdrom_probe_capabilities (ide_dr strcmp(drive->id->model, "MATSHITADVD-ROM SR-8174") == 0) cdi->mask &= ~CDC_PLAY_AUDIO; -#if ! STANDARD_ATAPI if (cdi->sanyo_slot > 0) { cdi->mask &= ~CDC_SELECT_DISC; nslots = 3; - } - - else -#endif /* not STANDARD_ATAPI */ - if (mechtype == mechtype_individual_changer || -
[PATCH 32/63] ide-cd: use BCD2BIN()/BIN2BCD() macros from
Use BCD2BIN()/BIN2BCD() macros from and remove the local bcd2bin()/bin2bcd() inlines. Signed-off-by: Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]> --- +15 bytes :( drivers/ide/ide-cd.c | 34 +++--- 1 file changed, 11 insertions(+), 23 deletions(-) Index: b/drivers/ide/ide-cd.c === --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -46,6 +46,7 @@ #include #include #include +#include #include /* For SCSI -> ATAPI command conversion */ @@ -1754,25 +1755,12 @@ ide_do_rw_cdrom (ide_drive_t *drive, str * can also be NULL, in which case no sense information is returned. */ -static inline -int bin2bcd (int x) -{ - return (x%10) | ((x/10) << 4); -} - - -static inline -int bcd2bin (int x) -{ - return (x >> 4) * 10 + (x & 0x0f); -} - static void msf_from_bcd (struct atapi_msf *msf) { - msf->minute = bcd2bin (msf->minute); - msf->second = bcd2bin (msf->second); - msf->frame = bcd2bin (msf->frame); + msf->minute = BCD2BIN(msf->minute); + msf->second = BCD2BIN(msf->second); + msf->frame = BCD2BIN(msf->frame); } static inline @@ -1999,8 +1987,8 @@ static int cdrom_read_toc(ide_drive_t *d return stat; if (info->cd_flags & IDE_CD_FLAG_TOCTRACKS_AS_BCD) { - toc->hdr.first_track = bcd2bin(toc->hdr.first_track); - toc->hdr.last_track = bcd2bin(toc->hdr.last_track); + toc->hdr.first_track = BCD2BIN(toc->hdr.first_track); + toc->hdr.last_track = BCD2BIN(toc->hdr.last_track); } ntracks = toc->hdr.last_track - toc->hdr.first_track + 1; @@ -2037,8 +2025,8 @@ static int cdrom_read_toc(ide_drive_t *d return stat; if (info->cd_flags & IDE_CD_FLAG_TOCTRACKS_AS_BCD) { - toc->hdr.first_track = bin2bcd(CDROM_LEADOUT); - toc->hdr.last_track = bin2bcd(CDROM_LEADOUT); + toc->hdr.first_track = (u8)BIN2BCD(CDROM_LEADOUT); + toc->hdr.last_track = (u8)BIN2BCD(CDROM_LEADOUT); } else { toc->hdr.first_track = CDROM_LEADOUT; toc->hdr.last_track = CDROM_LEADOUT; @@ -2051,14 +2039,14 @@ static int cdrom_read_toc(ide_drive_t *d toc->hdr.toc_length = ntohs (toc->hdr.toc_length); if (info->cd_flags & IDE_CD_FLAG_TOCTRACKS_AS_BCD) { - toc->hdr.first_track = bcd2bin(toc->hdr.first_track); - toc->hdr.last_track = bcd2bin(toc->hdr.last_track); + toc->hdr.first_track = BCD2BIN(toc->hdr.first_track); + toc->hdr.last_track = BCD2BIN(toc->hdr.last_track); } for (i = 0; i <= ntracks; i++) { if (info->cd_flags & IDE_CD_FLAG_TOCADDR_AS_BCD) { if (info->cd_flags & IDE_CD_FLAG_TOCTRACKS_AS_BCD) - toc->ent[i].track = bcd2bin(toc->ent[i].track); + toc->ent[i].track = BCD2BIN(toc->ent[i].track); msf_from_bcd(>ent[i].addr.msf); } toc->ent[i].addr.lba = msf_to_lba (toc->ent[i].addr.msf.minute, -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 37/63] ide-cd: factor out ioctl handlers from ide_cdrom_audio_ioctl()
Signed-off-by: Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]> --- drivers/ide/ide-cd.c | 142 ++- 1 file changed, 75 insertions(+), 67 deletions(-) Index: b/drivers/ide/ide-cd.c === --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -1977,6 +1977,24 @@ static int cdrom_read_toc(ide_drive_t *d return 0; } +static int ide_cd_read_tochdr(ide_drive_t *drive, void *arg) +{ + struct cdrom_info *cd = drive->driver_data; + struct cdrom_tochdr *tochdr = arg; + struct atapi_toc *toc; + int stat; + + /* Make sure our saved TOC is valid. */ + stat = cdrom_read_toc(drive, NULL); + if (stat) + return stat; + + toc = cd->toc; + tochdr->cdth_trk0 = toc->hdr.first_track; + tochdr->cdth_trk1 = toc->hdr.last_track; + + return 0; +} static int cdrom_read_subchannel(ide_drive_t *drive, int format, char *buf, int buflen, struct request_sense *sense) @@ -2071,6 +2089,55 @@ static int cdrom_get_toc_entry(ide_drive return 0; } +static int ide_cd_read_tocentry(ide_drive_t *drive, void *arg) +{ + struct cdrom_tocentry *tocentry = arg; + struct atapi_toc_entry *toce; + int stat; + + stat = cdrom_get_toc_entry(drive, tocentry->cdte_track, ); + if (stat) + return stat; + + tocentry->cdte_ctrl = toce->control; + tocentry->cdte_adr = toce->adr; + if (tocentry->cdte_format == CDROM_MSF) { + lba_to_msf(toce->addr.lba, + >cdte_addr.msf.minute, + >cdte_addr.msf.second, + >cdte_addr.msf.frame); + } else + tocentry->cdte_addr.lba = toce->addr.lba; + + return 0; +} + +static int ide_cd_fake_play_trkind(ide_drive_t *drive, void *arg) +{ + struct cdrom_ti *ti = arg; + struct atapi_toc_entry *first_toc, *last_toc; + unsigned long lba_start, lba_end; + int stat; + + stat = cdrom_get_toc_entry(drive, ti->cdti_trk0, _toc); + if (stat) + return stat; + + stat = cdrom_get_toc_entry(drive, ti->cdti_trk1, _toc); + if (stat) + return stat; + + if (ti->cdti_trk1 != CDROM_LEADOUT) + ++last_toc; + lba_start = first_toc->addr.lba; + lba_end = last_toc->addr.lba; + + if (lba_end <= lba_start) + return -EINVAL; + + return cdrom_play_audio(drive, lba_start, lba_end); +} + /* the generic packet interface to cdrom.c */ static int ide_cdrom_packet(struct cdrom_device_info *cdi, struct packet_command *cgc) @@ -2102,81 +2169,22 @@ static int ide_cdrom_packet(struct cdrom return cgc->stat; } -static -int ide_cdrom_audio_ioctl (struct cdrom_device_info *cdi, - unsigned int cmd, void *arg) - +static int ide_cdrom_audio_ioctl(struct cdrom_device_info *cdi, +unsigned int cmd, void *arg) { ide_drive_t *drive = cdi->handle; - struct cdrom_info *info = drive->driver_data; - int stat; switch (cmd) { /* * emulate PLAY_AUDIO_TI command with PLAY_AUDIO_10, since * atapi doesn't support it */ - case CDROMPLAYTRKIND: { - unsigned long lba_start, lba_end; - struct cdrom_ti *ti = arg; - struct atapi_toc_entry *first_toc, *last_toc; - - stat = cdrom_get_toc_entry(drive, ti->cdti_trk0, _toc); - if (stat) - return stat; - - stat = cdrom_get_toc_entry(drive, ti->cdti_trk1, _toc); - if (stat) - return stat; - - if (ti->cdti_trk1 != CDROM_LEADOUT) - ++last_toc; - lba_start = first_toc->addr.lba; - lba_end = last_toc->addr.lba; - - if (lba_end <= lba_start) - return -EINVAL; - - return cdrom_play_audio(drive, lba_start, lba_end); - } - - case CDROMREADTOCHDR: { - struct cdrom_tochdr *tochdr = arg; - struct atapi_toc *toc; - - /* Make sure our saved TOC is valid. */ - stat = cdrom_read_toc(drive, NULL); - if (stat) - return stat; - - toc = info->toc; - tochdr->cdth_trk0 = toc->hdr.first_track; - tochdr->cdth_trk1 = toc->hdr.last_track; - - return 0; - } - - case CDROMREADTOCENTRY: { - struct cdrom_tocentry *tocentry = arg; - struct atapi_toc_entry *toce; - - stat = cdrom_get_toc_entry(drive, tocentry->cdte_track, ); - if (stat) - return
[PATCH 33/63] ide-cd: re-organize handling of quirky devices
Re-organize handling of quirky devices: * Add struct cd_list_entry, ide_cd_quirks_list[] and ide_cd_flags() helper. * Set flags returned by ide_cd_flags() in ide_cdrom_setup(). * Add IDE_CD_FLAG_VERTOS_{300_SSD,600_ESD} and IDE_CD_FLAG_SANYO_3CD flags. * Move device quirks from ide_cdrom_setup() to ide_cd_quirks_list[]. * Rename IDE_CD_FLAG_NEC260 to IDE_CD_FLAG_PRE_ATAPI12 and handle quirky Stingray 8X CD-ROM using ide_cd_quirks_list[]. * Add IDE_CD_FLAG_FULL_CAPS_PAGE flag and handle quirky ACER 50X CD-ROM / WPI 32X CD-ROM using ide_cd_quirk_list[]. * Add IDE_CD_FLAG_PLAY_AUDIO_OK flag and handle quirky MATSHITA DVD-ROMs using ide_cd_quirks_list[]. * Add IDE_CD_FLAG_LE_SPEED_FIELDS flag and handle quirky ACER/AOpen 24X CD-ROM using ide_cd_quirk_list[]. * Fix some comments about quirky devices while at it. There should be no functionality changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]> --- drivers/ide/ide-cd.c | 138 --- drivers/ide/ide-cd.h | 10 ++- 2 files changed, 84 insertions(+), 64 deletions(-) Index: b/drivers/ide/ide-cd.c === --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -2356,12 +2356,7 @@ static int ide_cdrom_get_capabilities(id struct packet_command cgc; int stat, attempts = 3, size = ATAPI_CAPABILITIES_PAGE_SIZE; - /* -* ACER50 (and others?) require the full spec length mode sense -* page capabilities size, but older drives break. -*/ - if (!(!strcmp(drive->id->model, "ATAPI CD ROM DRIVE 50X MAX") || - !strcmp(drive->id->model, "WPI CDS-32X"))) + if ((info->cd_flags & IDE_CD_FLAG_FULL_CAPS_PAGE) == 0) size -= ATAPI_CAPABILITIES_PAGE_PAD_SIZE; init_cdrom_command(, buf, size, CGC_DATA_UNKNOWN); @@ -2381,9 +2376,7 @@ static void ide_cdrom_update_speed(ide_d curspeed = *(u16 *)[8 + 8]; maxspeed = *(u16 *)[8 + 14]; - /* The ACER/AOpen 24X cdrom has the speed fields byte-swapped */ - if (!drive->id->model[0] && - !strncmp(drive->id->fw_rev, "241N", 4)) { + if (cd->cd_flags & IDE_CD_FLAG_LE_SPEED_FIELDS) { curspeed = le16_to_cpu(curspeed); maxspeed = le16_to_cpu(maxspeed); } else { @@ -2606,8 +2599,7 @@ int ide_cdrom_probe_capabilities (ide_dr return nslots; } - if ((cd->cd_flags & IDE_CD_FLAG_NEC260) || - !strcmp(drive->id->model,"STINGRAY 8422 IDE 8X CD-ROM 7-27-95")) { + if (cd->cd_flags & IDE_CD_FLAG_PRE_ATAPI12) { cd->cd_flags &= ~IDE_CD_FLAG_NO_EJECT; cdi->mask &= ~CDC_PLAY_AUDIO; return nslots; @@ -2640,22 +2632,13 @@ int ide_cdrom_probe_capabilities (ide_dr cdi->mask &= ~(CDC_DVD_RAM | CDC_RAM); if (buf[8 + 3] & 0x10) cdi->mask &= ~CDC_DVD_R; - if (buf[8 + 4] & 0x01) + if ((buf[8 + 4] & 0x01) || (cd->cd_flags & IDE_CD_FLAG_PLAY_AUDIO_OK)) cdi->mask &= ~CDC_PLAY_AUDIO; mechtype = buf[8 + 6] >> 5; if (mechtype == mechtype_caddy || mechtype == mechtype_popup) cdi->mask |= CDC_CLOSE_TRAY; - /* Some drives used by Apple don't advertise audio play -* but they do support reading TOC & audio datas -*/ - if (strcmp(drive->id->model, "MATSHITADVD-ROM SR-8187") == 0 || - strcmp(drive->id->model, "MATSHITADVD-ROM SR-8186") == 0 || - strcmp(drive->id->model, "MATSHITADVD-ROM SR-8176") == 0 || - strcmp(drive->id->model, "MATSHITADVD-ROM SR-8174") == 0) - cdi->mask &= ~CDC_PLAY_AUDIO; - if (cdi->sanyo_slot > 0) { cdi->mask &= ~CDC_SELECT_DISC; nslots = 3; @@ -2784,11 +2767,74 @@ static int ide_cdrom_prep_fn(struct requ return 0; } +struct cd_list_entry { + const char *id_model; + const char *id_firmware; + unsigned intcd_flags; +}; + +static const struct cd_list_entry ide_cd_quirks_list[] = { + /* Limit transfer size per interrupt. */ + { "SAMSUNG CD-ROM SCR-2430", NULL, IDE_CD_FLAG_LIMIT_NFRAMES }, + { "SAMSUNG CD-ROM SCR-2432", NULL, IDE_CD_FLAG_LIMIT_NFRAMES }, + /* SCR-3231 doesn't support the SET_CD_SPEED command. */ + { "SAMSUNG CD-ROM SCR-3231", NULL, IDE_CD_FLAG_NO_SPEED_SELECT}, + /* Old NEC260 (not R) was released before ATAPI 1.2 spec. */ + { "NEC CD-ROM DRIVE:260","1.01", IDE_CD_FLAG_TOCADDR_AS_BCD | +IDE_CD_FLAG_PRE_ATAPI12, }, + /* Vertos 300, some versions of this drive like to talk BCD. */ + { "V003S0DS",NULL, IDE_CD_FLAG_VERTOS_300_SSD,}, + /* Vertos 600 ESD. */ + { "V006E0DS",NULL,
[PATCH 39/63] ide-cd: merge cdrom_read_subchannel() into ide_cdrom_get_mcn()
Signed-off-by: Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]> --- -19 bytes drivers/ide/ide-cd.c | 53 --- 1 file changed, 21 insertions(+), 32 deletions(-) Index: b/drivers/ide/ide-cd.c === --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -1996,25 +1996,6 @@ static int ide_cd_read_tochdr(ide_drive_ return 0; } -static int cdrom_read_subchannel(ide_drive_t *drive, int format, char *buf, -int buflen, struct request_sense *sense) -{ - struct request req; - - cdrom_prepare_request(drive, ); - - req.sense = sense; - req.data = buf; - req.data_len = buflen; - req.cmd[0] = GPCMD_READ_SUBCHANNEL; - req.cmd[1] = 2; /* MSF addressing */ - req.cmd[2] = 0x40; /* request subQ data */ - req.cmd[3] = format; - req.cmd[7] = (buflen >> 8); - req.cmd[8] = (buflen & 0xff); - return cdrom_queue_packet_command(drive, ); -} - /* ATAPI cdrom drives are free to select the speed you request or any slower rate :-( Requesting too fast a speed will _not_ produce an error. */ static int cdrom_select_speed(ide_drive_t *drive, int speed, @@ -2356,28 +2337,36 @@ int ide_cdrom_get_last_session (struct c return 0; } -static -int ide_cdrom_get_mcn (struct cdrom_device_info *cdi, - struct cdrom_mcn *mcn_info) +static int ide_cdrom_get_mcn(struct cdrom_device_info *cdi, +struct cdrom_mcn *mcn_info) { - int stat; - char mcnbuf[24]; ide_drive_t *drive = cdi->handle; + int stat, mcnlen; + struct request rq; + char buf[24]; + + cdrom_prepare_request(drive, ); + + rq.data = buf; + rq.data_len = sizeof(buf); -/* get MCN */ - if ((stat = cdrom_read_subchannel(drive, 2, mcnbuf, sizeof (mcnbuf), NULL))) + rq.cmd[0] = GPCMD_READ_SUBCHANNEL; + rq.cmd[1] = 2; /* MSF addressing */ + rq.cmd[2] = 0x40; /* request subQ data */ + rq.cmd[3] = 2; /* format */ + rq.cmd[8] = sizeof(buf); + + stat = cdrom_queue_packet_command(drive, ); + if (stat) return stat; - memcpy (mcn_info->medium_catalog_number, mcnbuf+9, - sizeof (mcn_info->medium_catalog_number)-1); - mcn_info->medium_catalog_number[sizeof (mcn_info->medium_catalog_number)-1] - = '\0'; + mcnlen = sizeof(mcn_info->medium_catalog_number) - 1; + memcpy(mcn_info->medium_catalog_number, buf + 9, mcnlen); + mcn_info->medium_catalog_number[mcnlen] = '\0'; return 0; } - - / * Other driver requests (open, close, check media change). */ -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 40/63] ide-cd: merge cdrom_select_speed() into ide_cdrom_select_speed()
Signed-off-by: Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]> --- -13 bytes drivers/ide/ide-cd.c | 66 ++- 1 file changed, 29 insertions(+), 37 deletions(-) Index: b/drivers/ide/ide-cd.c === --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -1996,38 +1996,6 @@ static int ide_cd_read_tochdr(ide_drive_ return 0; } -/* ATAPI cdrom drives are free to select the speed you request or any slower - rate :-( Requesting too fast a speed will _not_ produce an error. */ -static int cdrom_select_speed(ide_drive_t *drive, int speed, - struct request_sense *sense) -{ - struct cdrom_info *cd = drive->driver_data; - struct cdrom_device_info *cdi = >devinfo; - struct request req; - cdrom_prepare_request(drive, ); - - req.sense = sense; - if (speed == 0) - speed = 0x; /* set to max */ - else - speed *= 177; /* Nx to kbytes/s */ - - req.cmd[0] = GPCMD_SET_SPEED; - /* Read Drive speed in kbytes/second MSB */ - req.cmd[2] = (speed >> 8) & 0xff; - /* Read Drive speed in kbytes/second LSB */ - req.cmd[3] = speed & 0xff; - if ((cdi->mask & (CDC_CD_R | CDC_CD_RW | CDC_DVD_R)) != - (CDC_CD_R | CDC_CD_RW | CDC_DVD_R)) { - /* Write Drive speed in kbytes/second MSB */ - req.cmd[4] = (speed >> 8) & 0xff; - /* Write Drive speed in kbytes/second LSB */ - req.cmd[5] = speed & 0xff; - } - - return cdrom_queue_packet_command(drive, ); -} - static int cdrom_get_toc_entry(ide_drive_t *drive, int track, struct atapi_toc_entry **ent) { @@ -2251,23 +2219,47 @@ static void ide_cdrom_update_speed(ide_d cd->max_speed = (maxspeed + (176/2)) / 176; } -static -int ide_cdrom_select_speed (struct cdrom_device_info *cdi, int speed) +/* + * ATAPI devices are free to select the speed you request or any slower + * rate. :-( Requesting too fast a speed will _not_ produce an error. + */ +static int ide_cdrom_select_speed(struct cdrom_device_info *cdi, int speed) { ide_drive_t *drive = cdi->handle; struct cdrom_info *cd = drive->driver_data; + struct request rq; struct request_sense sense; u8 buf[ATAPI_CAPABILITIES_PAGE_SIZE]; int stat; - if ((stat = cdrom_select_speed(drive, speed, )) < 0) - return stat; + cdrom_prepare_request(drive, ); + + rq.sense = + + if (speed == 0) + speed = 0x; /* set to max */ + else + speed *= 177; /* Nx to kbytes/s */ + + rq.cmd[0] = GPCMD_SET_SPEED; + /* Read Drive speed in kbytes/second MSB/LSB */ + rq.cmd[2] = (speed >> 8) & 0xff; + rq.cmd[3] = speed & 0xff; + if ((cdi->mask & (CDC_CD_R | CDC_CD_RW | CDC_DVD_R)) != + (CDC_CD_R | CDC_CD_RW | CDC_DVD_R)) { + /* Write Drive speed in kbytes/second MSB/LSB */ + rq.cmd[4] = (speed >> 8) & 0xff; + rq.cmd[5] = speed & 0xff; + } + + stat = cdrom_queue_packet_command(drive, ); if (!ide_cdrom_get_capabilities(drive, buf)) { ide_cdrom_update_speed(drive, buf); cdi->speed = cd->current_speed; } -return 0; + + return 0; } /* -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 42/63] ide-cd: coding style fixes for cdrom_get_toc_entry()
This is a preparation to move code handling cdrom.c IOCTLs out of ide-cd.c. Signed-off-by: Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]> --- drivers/ide/ide-cd.c |8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) Index: b/drivers/ide/ide-cd.c === --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -1993,11 +1993,13 @@ static int cdrom_get_toc_entry(ide_drive /* Check validity of requested track number. */ ntracks = toc->hdr.last_track - toc->hdr.first_track + 1; - if (toc->hdr.first_track == CDROM_LEADOUT) ntracks = 0; + + if (toc->hdr.first_track == CDROM_LEADOUT) + ntracks = 0; + if (track == CDROM_LEADOUT) *ent = >ent[ntracks]; - else if (track < toc->hdr.first_track || -track > toc->hdr.last_track) + else if (track < toc->hdr.first_track || track > toc->hdr.last_track) return -EINVAL; else *ent = >ent[track - toc->hdr.first_track]; -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 13/63] ide-cd: fix DMA error handling in cdrom_newpc_intr()
Make cdrom_newpc_intr() match cdrom_{read,write}_intr() w.r.t. handling DMA errors: * disable DMA before cdrom_decode_status() call * log the device name and the type of the request (read/write) Signed-off-by: Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]> --- drivers/ide/ide-cd.c | 10 ++ 1 file changed, 6 insertions(+), 4 deletions(-) Index: b/drivers/ide/ide-cd.c === --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -1663,6 +1663,11 @@ static ide_startstop_t cdrom_newpc_intr( if (dma) { info->dma = 0; dma_error = HWIF(drive)->ide_dma_end(drive); + if (dma_error) { + printk(KERN_ERR "%s: DMA %s error\n", drive->name, + rq_data_dir(rq) ? "write" : "read"); + ide_dma_off(drive); + } } if (cdrom_decode_status(drive, 0, )) @@ -1672,11 +1677,8 @@ static ide_startstop_t cdrom_newpc_intr( * using dma, transfer is complete now */ if (dma) { - if (dma_error) { - printk(KERN_ERR "ide-cd: dma error\n"); - ide_dma_off(drive); + if (dma_error) return ide_error(drive, "dma error", stat); - } end_that_request_chunk(rq, 1, rq->data_len); rq->data_len = 0; -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 41/63] ide-cd: move lba_to_msf() and msf_to_lba() to
* Move lba_to_msf() and msf_to_lba() to (use 'u8' type instead of 'byte' while at it). * Remove msf_to_lba() copy from drivers/cdrom/cdrom.c. Cc: Jens Axboe <[EMAIL PROTECTED]> Signed-off-by: Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]> --- drivers/cdrom/cdrom.c |6 -- drivers/ide/ide-cd.c | 18 -- include/linux/cdrom.h | 14 ++ 3 files changed, 14 insertions(+), 24 deletions(-) Index: b/drivers/cdrom/cdrom.c === --- a/drivers/cdrom/cdrom.c +++ b/drivers/cdrom/cdrom.c @@ -2787,12 +2787,6 @@ int cdrom_ioctl(struct file * file, stru return -ENOSYS; } -static inline -int msf_to_lba(char m, char s, char f) -{ - return (((m * CD_SECS) + s) * CD_FRAMES + f) - CD_MSF_OFFSET; -} - /* * Required when we need to use READ_10 to issue other than 2048 block * reads Index: b/drivers/ide/ide-cd.c === --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -1643,24 +1643,6 @@ void msf_from_bcd (struct atapi_msf *msf msf->frame = BCD2BIN(msf->frame); } -static inline -void lba_to_msf (int lba, byte *m, byte *s, byte *f) -{ - lba += CD_MSF_OFFSET; - lba &= 0xff; /* negative lbas use only 24 bits */ - *m = lba / (CD_SECS * CD_FRAMES); - lba %= (CD_SECS * CD_FRAMES); - *s = lba / CD_FRAMES; - *f = lba % CD_FRAMES; -} - - -static inline -int msf_to_lba (byte m, byte s, byte f) -{ - return (((m * CD_SECS) + s) * CD_FRAMES + f) - CD_MSF_OFFSET; -} - static int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense) { struct request req; Index: b/include/linux/cdrom.h === --- a/include/linux/cdrom.h +++ b/include/linux/cdrom.h @@ -1184,6 +1184,20 @@ struct media_event_desc { extern int cdrom_get_media_event(struct cdrom_device_info *cdi, struct media_event_desc *med); +static inline void lba_to_msf(int lba, u8 *m, u8 *s, u8 *f) +{ + lba += CD_MSF_OFFSET; + lba &= 0xff; /* negative lbas use only 24 bits */ + *m = lba / (CD_SECS * CD_FRAMES); + lba %= (CD_SECS * CD_FRAMES); + *s = lba / CD_FRAMES; + *f = lba % CD_FRAMES; +} + +static inline int msf_to_lba(u8 m, u8 s, u8 f) +{ + return (((m * CD_SECS) + s) * CD_FRAMES + f) - CD_MSF_OFFSET; +} #endif /* End of kernel only stuff */ #endif /* _LINUX_CDROM_H */ -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 45/63] ide-cd: remove BUG_ON() from cdrom_newpc_intr()
There is no need for it anylonger and ide_set_handler() complains if ->handler is not NULL anyway. Signed-off-by: Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]> --- drivers/ide/ide-cd.c |2 -- 1 file changed, 2 deletions(-) Index: b/drivers/ide/ide-cd.c === --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -1368,8 +1368,6 @@ static ide_startstop_t cdrom_newpc_intr( if (len > 0) ide_cd_pad_transfer(drive, xferfunc, len); - BUG_ON(HWGROUP(drive)->handler != NULL); - ide_set_handler(drive, cdrom_newpc_intr, rq->timeout, NULL); return ide_started; -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 43/63] ide-cd: rename cdrom_* functions to ide_cd_*
* cdrom_prepare_request() -> ide_cd_init_rq() * cdrom_queue_packet_command() -> ide_cd_queue_pc() * cdrom_lockdoor() -> ide_cd_lockdoor() * cdrom_read_toc() -> ide_cd_read_toc() * cdrom_get_toc_entry() -> ide_cd_get_toc_entry() This is a preparation to move code handling cdrom.c IOCTLs out of ide-cd.c. Signed-off-by: Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]> --- drivers/ide/ide-cd.c | 83 +++ 1 file changed, 44 insertions(+), 39 deletions(-) Index: b/drivers/ide/ide-cd.c === --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -206,7 +206,7 @@ void cdrom_analyze_sense_data(ide_drive_ /* * Initialize a ide-cd packet command request */ -static void cdrom_prepare_request(ide_drive_t *drive, struct request *rq) +static void ide_cd_init_rq(ide_drive_t *drive, struct request *rq) { struct cdrom_info *cd = drive->driver_data; @@ -225,7 +225,7 @@ static void cdrom_queue_request_sense(id sense = >sense_data; /* stuff the sense request in front of our current request */ - cdrom_prepare_request(drive, rq); + ide_cd_init_rq(drive, rq); rq->data = sense; rq->cmd[0] = GPCMD_REQUEST_SENSE; @@ -1168,8 +1168,7 @@ static ide_startstop_t cdrom_do_packet_c return cdrom_start_packet_command(drive, len, cdrom_do_pc_continuation); } - -static int cdrom_queue_packet_command(ide_drive_t *drive, struct request *rq) +static int ide_cd_queue_pc(ide_drive_t *drive, struct request *rq) { struct request_sense sense; int retries = 10; @@ -1649,7 +1648,7 @@ static int cdrom_check_status(ide_drive_ struct cdrom_info *info = drive->driver_data; struct cdrom_device_info *cdi = >devinfo; - cdrom_prepare_request(drive, ); + ide_cd_init_rq(drive, ); req.sense = sense; req.cmd[0] = GPCMD_TEST_UNIT_READY; @@ -1661,13 +1660,12 @@ static int cdrom_check_status(ide_drive_ */ req.cmd[7] = cdi->sanyo_slot % 3; - return cdrom_queue_packet_command(drive, ); + return ide_cd_queue_pc(drive, ); } - /* Lock the door if LOCKFLAG is nonzero; unlock it otherwise. */ -static int -cdrom_lockdoor(ide_drive_t *drive, int lockflag, struct request_sense *sense) +static int ide_cd_lockdoor(ide_drive_t *drive, int lockflag, + struct request_sense *sense) { struct cdrom_info *cd = drive->driver_data; struct request_sense my_sense; @@ -1681,11 +1679,11 @@ cdrom_lockdoor(ide_drive_t *drive, int l if (cd->cd_flags & IDE_CD_FLAG_NO_DOORLOCK) { stat = 0; } else { - cdrom_prepare_request(drive, ); + ide_cd_init_rq(drive, ); req.sense = sense; req.cmd[0] = GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL; req.cmd[4] = lockflag ? 1 : 0; - stat = cdrom_queue_packet_command(drive, ); + stat = ide_cd_queue_pc(drive, ); } /* If we got an illegal field error, the drive @@ -1731,7 +1729,7 @@ static int cdrom_eject(ide_drive_t *driv if ((cd->cd_flags & IDE_CD_FLAG_DOOR_LOCKED) && ejectflag) return 0; - cdrom_prepare_request(drive, ); + ide_cd_init_rq(drive, ); /* only tell drive to close tray if open, if it can do that */ if (ejectflag && (cdi->mask & CDC_CLOSE_TRAY)) @@ -1740,7 +1738,8 @@ static int cdrom_eject(ide_drive_t *driv req.sense = sense; req.cmd[0] = GPCMD_START_STOP_UNIT; req.cmd[4] = loej | (ejectflag != 0); - return cdrom_queue_packet_command(drive, ); + + return ide_cd_queue_pc(drive, ); } static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity, @@ -1755,7 +1754,7 @@ static int cdrom_read_capacity(ide_drive int stat; struct request req; - cdrom_prepare_request(drive, ); + ide_cd_init_rq(drive, ); req.sense = sense; req.cmd[0] = GPCMD_READ_CDVD_CAPACITY; @@ -1763,7 +1762,7 @@ static int cdrom_read_capacity(ide_drive req.data_len = sizeof(capbuf); req.cmd_flags |= REQ_QUIET; - stat = cdrom_queue_packet_command(drive, ); + stat = ide_cd_queue_pc(drive, ); if (stat == 0) { *capacity = 1 + be32_to_cpu(capbuf.lba); *sectors_per_frame = @@ -1779,7 +1778,7 @@ static int cdrom_read_tocentry(ide_drive { struct request req; - cdrom_prepare_request(drive, ); + ide_cd_init_rq(drive, ); req.sense = sense; req.data = buf; @@ -1794,12 +1793,12 @@ static int cdrom_read_tocentry(ide_drive if (msf_flag) req.cmd[1] = 2; - return cdrom_queue_packet_command(drive, ); + return ide_cd_queue_pc(drive, ); } /* Try to read the entire TOC for the disk into our internal buffer. */ -static int
[PATCH 44/63] ide-cd: move code handling cdrom.c IOCTLs to ide-cd_ioctl.c
There should be no functionality changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]> --- drivers/ide/Makefile |2 drivers/ide/ide-cd.c | 271 + drivers/ide/ide-cd.h | 17 ++ drivers/ide/ide-cd_ioctl.c | 265 4 files changed, 290 insertions(+), 265 deletions(-) Index: b/drivers/ide/Makefile === --- a/drivers/ide/Makefile +++ b/drivers/ide/Makefile @@ -40,7 +40,7 @@ obj-$(CONFIG_BLK_DEV_IDEPNP) += ide-pnp obj-$(CONFIG_IDE_H8300)+= h8300/ obj-$(CONFIG_IDE_GENERIC) += ide-generic.o -ide-cd_mod-y += ide-cd.o ide-cd_verbose.o +ide-cd_mod-y += ide-cd.o ide-cd_ioctl.o ide-cd_verbose.o obj-$(CONFIG_BLK_DEV_IDEDISK) += ide-disk.o obj-$(CONFIG_BLK_DEV_IDECD)+= ide-cd_mod.o Index: b/drivers/ide/ide-cd.c === --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -206,7 +206,7 @@ void cdrom_analyze_sense_data(ide_drive_ /* * Initialize a ide-cd packet command request */ -static void ide_cd_init_rq(ide_drive_t *drive, struct request *rq) +void ide_cd_init_rq(ide_drive_t *drive, struct request *rq) { struct cdrom_info *cd = drive->driver_data; @@ -1168,7 +1168,7 @@ static ide_startstop_t cdrom_do_packet_c return cdrom_start_packet_command(drive, len, cdrom_do_pc_continuation); } -static int ide_cd_queue_pc(ide_drive_t *drive, struct request *rq) +int ide_cd_queue_pc(ide_drive_t *drive, struct request *rq) { struct request_sense sense; int retries = 10; @@ -1664,8 +1664,8 @@ static int cdrom_check_status(ide_drive_ } /* Lock the door if LOCKFLAG is nonzero; unlock it otherwise. */ -static int ide_cd_lockdoor(ide_drive_t *drive, int lockflag, - struct request_sense *sense) +int ide_cd_lockdoor(ide_drive_t *drive, int lockflag, + struct request_sense *sense) { struct cdrom_info *cd = drive->driver_data; struct request_sense my_sense; @@ -1796,9 +1796,8 @@ static int cdrom_read_tocentry(ide_drive return ide_cd_queue_pc(drive, ); } - /* Try to read the entire TOC for the disk into our internal buffer. */ -static int ide_cd_read_toc(ide_drive_t *drive, struct request_sense *sense) +int ide_cd_read_toc(ide_drive_t *drive, struct request_sense *sense) { int stat, ntracks, i; struct cdrom_info *info = drive->driver_data; @@ -1958,112 +1957,6 @@ static int ide_cd_read_toc(ide_drive_t * return 0; } -static int ide_cd_read_tochdr(ide_drive_t *drive, void *arg) -{ - struct cdrom_info *cd = drive->driver_data; - struct cdrom_tochdr *tochdr = arg; - struct atapi_toc *toc; - int stat; - - /* Make sure our saved TOC is valid. */ - stat = ide_cd_read_toc(drive, NULL); - if (stat) - return stat; - - toc = cd->toc; - tochdr->cdth_trk0 = toc->hdr.first_track; - tochdr->cdth_trk1 = toc->hdr.last_track; - - return 0; -} - -static int ide_cd_get_toc_entry(ide_drive_t *drive, int track, - struct atapi_toc_entry **ent) -{ - struct cdrom_info *info = drive->driver_data; - struct atapi_toc *toc = info->toc; - int ntracks; - - /* -* don't serve cached data, if the toc isn't valid -*/ - if ((info->cd_flags & IDE_CD_FLAG_TOC_VALID) == 0) - return -EINVAL; - - /* Check validity of requested track number. */ - ntracks = toc->hdr.last_track - toc->hdr.first_track + 1; - - if (toc->hdr.first_track == CDROM_LEADOUT) - ntracks = 0; - - if (track == CDROM_LEADOUT) - *ent = >ent[ntracks]; - else if (track < toc->hdr.first_track || track > toc->hdr.last_track) - return -EINVAL; - else - *ent = >ent[track - toc->hdr.first_track]; - - return 0; -} - -static int ide_cd_read_tocentry(ide_drive_t *drive, void *arg) -{ - struct cdrom_tocentry *tocentry = arg; - struct atapi_toc_entry *toce; - int stat; - - stat = ide_cd_get_toc_entry(drive, tocentry->cdte_track, ); - if (stat) - return stat; - - tocentry->cdte_ctrl = toce->control; - tocentry->cdte_adr = toce->adr; - if (tocentry->cdte_format == CDROM_MSF) { - lba_to_msf(toce->addr.lba, - >cdte_addr.msf.minute, - >cdte_addr.msf.second, - >cdte_addr.msf.frame); - } else - tocentry->cdte_addr.lba = toce->addr.lba; - - return 0; -} - -static int ide_cd_fake_play_trkind(ide_drive_t *drive, void *arg) -{ - struct cdrom_ti *ti = arg; - struct atapi_toc_entry *first_toc,
[PATCH 49/63] ide-cd: merge cdrom_pc_intr() and cdrom_newpc_intr()
Add handling of REQ_TYPE_{SENSE,ATA_PC} requests to cdrom_newpc_intr() (please note that these requests never have 'bio' attached to them and they never use DMA), then remove no longer needed cdrom_pc_intr(). There should be no functionality changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]> --- -264 bytes drivers/ide/ide-cd.c | 159 +-- 1 file changed, 55 insertions(+), 104 deletions(-) Index: b/drivers/ide/ide-cd.c === --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -1061,90 +1061,7 @@ static void ide_cd_request_sense_fixup(s } } -/* Interrupt routine for packet command completion. */ -static ide_startstop_t cdrom_pc_intr (ide_drive_t *drive) -{ - struct request *rq = HWGROUP(drive)->rq; - xfer_func_t *xferfunc = NULL; - int stat, ireason, len, thislen, write, update; - u8 lowcyl = 0, highcyl = 0; - - /* Check for errors. */ - if (cdrom_decode_status(drive, 0, )) - return ide_stopped; - - /* Read the interrupt reason and the transfer length. */ - ireason = HWIF(drive)->INB(IDE_IREASON_REG) & 0x3; - lowcyl = HWIF(drive)->INB(IDE_BCOUNTL_REG); - highcyl = HWIF(drive)->INB(IDE_BCOUNTH_REG); - - len = lowcyl + (256 * highcyl); - - /* If DRQ is clear, the command has completed. - Complain if we still have data left to transfer. */ - if ((stat & DRQ_STAT) == 0) { - ide_cd_request_sense_fixup(rq); - update = rq->data_len ? 0 : 1; - goto end_request; - } - - /* Figure out how much data to transfer. */ - thislen = rq->data_len; - if (thislen > len) - thislen = len; - - if (ireason == 0) { - write = 1; - xferfunc = HWIF(drive)->atapi_output_bytes; - } else if (ireason == 2) { - write = 0; - xferfunc = HWIF(drive)->atapi_input_bytes; - } - - if (xferfunc) { - if (!rq->data) { - printk(KERN_ERR "%s: confused, missing data\n", - drive->name); - blk_dump_rq_flags(rq, write ? "cdrom_pc_intr, write" - : "cdrom_pc_intr, read"); - goto pad; - } - /* Transfer the data. */ - xferfunc(drive, rq->data, thislen); - - /* Keep count of how much data we've moved. */ - len -= thislen; - rq->data += thislen; - rq->data_len -= thislen; - - if (write && blk_sense_request(rq)) - rq->sense_len += thislen; - } else { - printk (KERN_ERR "%s: cdrom_pc_intr: The drive " - "appears confused (ireason = 0x%02x). " - "Trying to recover by ending request.\n", - drive->name, ireason); - update = 0; - goto end_request; - } -pad: - /* -* If we haven't moved enough data to satisfy the drive, -* add some padding. -*/ - if (len > 0) - ide_cd_pad_transfer(drive, xferfunc, len); - - /* Now we wait for another interrupt. */ - ide_set_handler(drive, _pc_intr, ATAPI_WAIT_PC, cdrom_timer_expiry); - return ide_started; - -end_request: - if (!update) - rq->cmd_flags |= REQ_FAILED; - cdrom_end_request(drive, update); - return ide_stopped; -} +static ide_startstop_t cdrom_newpc_intr(ide_drive_t *); static ide_startstop_t cdrom_do_pc_continuation (ide_drive_t *drive) { @@ -1154,10 +1071,9 @@ static ide_startstop_t cdrom_do_pc_conti rq->timeout = ATAPI_WAIT_PC; /* Send the command to the drive and return. */ - return cdrom_transfer_packet_command(drive, rq, _pc_intr); + return cdrom_transfer_packet_command(drive, rq, cdrom_newpc_intr); } - static ide_startstop_t cdrom_do_packet_command (ide_drive_t *drive) { int len; @@ -1252,27 +1168,27 @@ static int cdrom_write_check_ireason(ide /* * best way to deal with dma that is not sector aligned right now... note * that in this path we are not using ->data or ->buffer at all. this irs - * can replace cdrom_pc_intr, cdrom_read_intr, and cdrom_write_intr in the - * future. + * can replace cdrom_read_intr() and cdrom_write_intr() in the future. */ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) { struct cdrom_info *info = drive->driver_data; struct request *rq = HWGROUP(drive)->rq; - int dma_error, dma, stat, ireason, len, thislen; - u8 lowcyl, highcyl; xfer_func_t *xferfunc; - unsigned long flags; + ide_expiry_t *expiry; + int dma_error = 0,
[PATCH 47/63] ide-cd: factor out request sense fixup from cdrom_pc_intr()
This is a preparation for cdrom_pc_intr() and cdrom_newpc_intr() merge. Signed-off-by: Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]> --- drivers/ide/ide-cd.c | 25 +++-- 1 file changed, 15 insertions(+), 10 deletions(-) Index: b/drivers/ide/ide-cd.c === --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -1047,6 +1047,20 @@ static ide_startstop_t cdrom_start_read * Execute all other packet commands. */ +static void ide_cd_request_sense_fixup(struct request *rq) +{ + /* +* Some of the trailing request sense fields are optional, +* and some drives don't send them. Sigh. +*/ + if (rq->cmd[0] == GPCMD_REQUEST_SENSE && + rq->data_len > 0 && rq->data_len <= 5) + while (rq->data_len > 0) { + *(u8 *)rq->data++ = 0; + --rq->data_len; + } +} + /* Interrupt routine for packet command completion. */ static ide_startstop_t cdrom_pc_intr (ide_drive_t *drive) { @@ -1069,16 +1083,7 @@ static ide_startstop_t cdrom_pc_intr (id /* If DRQ is clear, the command has completed. Complain if we still have data left to transfer. */ if ((stat & DRQ_STAT) == 0) { - /* Some of the trailing request sense fields are optional, and - some drives don't send them. Sigh. */ - if (rq->cmd[0] == GPCMD_REQUEST_SENSE && - rq->data_len > 0 && - rq->data_len <= 5) { - while (rq->data_len > 0) { - *(unsigned char *)rq->data++ = 0; - --rq->data_len; - } - } + ide_cd_request_sense_fixup(rq); if (rq->data_len == 0) cdrom_end_request(drive, 1); -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 46/63] ide-cd: call blk_dump_rq_flags() on "missing data" in cdrom_newpc_intr()
Signed-off-by: Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]> --- drivers/ide/ide-cd.c |6 +- 1 file changed, 5 insertions(+), 1 deletion(-) Index: b/drivers/ide/ide-cd.c === --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -1343,7 +1343,11 @@ static ide_startstop_t cdrom_newpc_intr( } if (!ptr) { - printk(KERN_ERR "%s: confused, missing data\n", drive->name); + printk(KERN_ERR "%s: confused, missing data\n", + drive->name); + blk_dump_rq_flags(rq, rq_data_dir(rq) + ? "cdrom_newpc_intr, write" + : "cdrom_newpc_intr, read"); break; } -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 12/63] ide-cd: fix "missing data" handling in cdrom_pc_intr()
If drive still wants to transfer the data we need to pad the transfer instead of just finishing the request. Signed-off-by: Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]> --- drivers/ide/ide-cd.c |7 --- 1 file changed, 4 insertions(+), 3 deletions(-) Index: b/drivers/ide/ide-cd.c === --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -1500,9 +1500,11 @@ static ide_startstop_t cdrom_pc_intr (id if (xferfunc) { if (!rq->data) { + printk(KERN_ERR "%s: confused, missing data\n", + drive->name); blk_dump_rq_flags(rq, write ? "cdrom_pc_intr, write" : "cdrom_pc_intr, read"); - goto confused; + goto pad; } /* Transfer the data. */ xferfunc(drive, rq->data, thislen); @@ -1515,7 +1517,6 @@ static ide_startstop_t cdrom_pc_intr (id if (write && blk_sense_request(rq)) rq->sense_len += thislen; } else { -confused: printk (KERN_ERR "%s: cdrom_pc_intr: The drive " "appears confused (ireason = 0x%02x). " "Trying to recover by ending request.\n", @@ -1524,7 +1525,7 @@ confused: cdrom_end_request(drive, 0); return ide_stopped; } - +pad: /* * If we haven't moved enough data to satisfy the drive, * add some padding. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 50/63] ide-cd: remove cdrom_do_pc_continuation()
cdrom_do_pc_continuation() is now identical to cdrom_do_newpc_cont() so just always use the latter function. Signed-off-by: Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]> --- -49 bytes drivers/ide/ide-cd.c | 15 ++- 1 file changed, 2 insertions(+), 13 deletions(-) Index: b/drivers/ide/ide-cd.c === --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -1061,18 +1061,7 @@ static void ide_cd_request_sense_fixup(s } } -static ide_startstop_t cdrom_newpc_intr(ide_drive_t *); - -static ide_startstop_t cdrom_do_pc_continuation (ide_drive_t *drive) -{ - struct request *rq = HWGROUP(drive)->rq; - - if (!rq->timeout) - rq->timeout = ATAPI_WAIT_PC; - - /* Send the command to the drive and return. */ - return cdrom_transfer_packet_command(drive, rq, cdrom_newpc_intr); -} +static ide_startstop_t cdrom_do_newpc_cont(ide_drive_t *); static ide_startstop_t cdrom_do_packet_command (ide_drive_t *drive) { @@ -1085,7 +1074,7 @@ static ide_startstop_t cdrom_do_packet_c len = rq->data_len; /* Start sending the command to the drive. */ - return cdrom_start_packet_command(drive, len, cdrom_do_pc_continuation); + return cdrom_start_packet_command(drive, len, cdrom_do_newpc_cont); } int ide_cd_queue_pc(ide_drive_t *drive, struct request *rq) -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 52/63] ide-cd: add ide_cd_drain_data() helper
Add ide_cd_drain_data() and use it in cdrom_{buffer_sectors,read_intr}() (as a nice side-effect this cuts 0.5kB of code from ide-cd.o). There should be no functionality changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]> --- -511 bytes drivers/ide/ide-cd.c | 28 +++- 1 file changed, 15 insertions(+), 13 deletions(-) Index: b/drivers/ide/ide-cd.c === --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -626,6 +626,16 @@ static void ide_cd_pad_transfer(ide_driv } } +static void ide_cd_drain_data(ide_drive_t *drive, int nsects) +{ + while (nsects > 0) { + static char dum[SECTOR_SIZE]; + + drive->hwif->atapi_input_bytes(drive, dum, sizeof(dum)); + nsects--; + } +} + /* * Buffer up to SECTORS_TO_TRANSFER sectors from the drive in our sector * buffer. Once the first sector is added, any subsequent sectors are @@ -664,11 +674,7 @@ static void cdrom_buffer_sectors (ide_dr } /* Throw away any remaining data. */ - while (sectors_to_transfer > 0) { - static char dum[SECTOR_SIZE]; - HWIF(drive)->atapi_input_bytes(drive, dum, sizeof (dum)); - --sectors_to_transfer; - } + ide_cd_drain_data(drive, sectors_to_transfer); } /* @@ -791,14 +797,10 @@ static ide_startstop_t cdrom_read_intr ( any of the leading sectors. */ nskip = min_t(int, rq->current_nr_sectors - bio_cur_sectors(rq->bio), sectors_to_transfer); - while (nskip > 0) { - /* We need to throw away a sector. */ - static char dum[SECTOR_SIZE]; - HWIF(drive)->atapi_input_bytes(drive, dum, sizeof (dum)); - - --rq->current_nr_sectors; - --nskip; - --sectors_to_transfer; + if (nskip > 0) { + ide_cd_drain_data(drive, nskip); + rq->current_nr_sectors -= nskip; + sectors_to_transfer -= nskip; } /* Now loop while we still have data to read from the drive. */ -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 51/63] ide-cd: merge cdrom_do_packet_command() and cdrom_do_block_pc()
Add REQ_TYPE_{SENSE,ATA_PC} requests handling to cdrom_do_block_pc() and remove cdrom_do_packet_command(). There should be no functionality changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]> --- -29 bytes drivers/ide/ide-cd.c | 25 + 1 file changed, 5 insertions(+), 20 deletions(-) Index: b/drivers/ide/ide-cd.c === --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -1061,22 +1061,6 @@ static void ide_cd_request_sense_fixup(s } } -static ide_startstop_t cdrom_do_newpc_cont(ide_drive_t *); - -static ide_startstop_t cdrom_do_packet_command (ide_drive_t *drive) -{ - int len; - struct request *rq = HWGROUP(drive)->rq; - struct cdrom_info *info = drive->driver_data; - - info->dma = 0; - rq->cmd_flags &= ~REQ_FAILED; - len = rq->data_len; - - /* Start sending the command to the drive. */ - return cdrom_start_packet_command(drive, len, cdrom_do_newpc_cont); -} - int ide_cd_queue_pc(ide_drive_t *drive, struct request *rq) { struct request_sense sense; @@ -1490,7 +1474,10 @@ static ide_startstop_t cdrom_do_block_pc { struct cdrom_info *info = drive->driver_data; - rq->cmd_flags |= REQ_QUIET; + if (blk_pc_request(rq)) + rq->cmd_flags |= REQ_QUIET; + else + rq->cmd_flags &= ~REQ_FAILED; info->dma = 0; @@ -1550,10 +1537,8 @@ ide_do_rw_cdrom (ide_drive_t *drive, str } info->last_block = block; return action; - } else if (rq->cmd_type == REQ_TYPE_SENSE || + } else if (blk_sense_request(rq) || blk_pc_request(rq) || rq->cmd_type == REQ_TYPE_ATA_PC) { - return cdrom_do_packet_command(drive); - } else if (blk_pc_request(rq)) { return cdrom_do_block_pc(drive, rq); } else if (blk_special_request(rq)) { /* -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 54/63] ide-cd: merge cdrom_read_intr() and cdrom_write_intr()
Add handling of read requests to cdrom_write_intr(), rename it to cdrom_rw_intr() and remove no longer needed cdrom_read_intr(). There should be no functionality changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]> --- -368 bytes drivers/ide/ide-cd.c | 207 +-- 1 file changed, 69 insertions(+), 138 deletions(-) Index: b/drivers/ide/ide-cd.c === --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -739,125 +739,6 @@ static int ide_cd_check_transfer_size(id } /* - * Interrupt routine. Called when a read request has completed. - */ -static ide_startstop_t cdrom_read_intr (ide_drive_t *drive) -{ - int stat; - int ireason, len, sectors_to_transfer, nskip; - struct cdrom_info *info = drive->driver_data; - u8 lowcyl = 0, highcyl = 0; - int dma = info->dma, dma_error = 0; - - struct request *rq = HWGROUP(drive)->rq; - - /* -* handle dma case -*/ - if (dma) { - info->dma = 0; - dma_error = HWIF(drive)->ide_dma_end(drive); - if (dma_error) { - printk(KERN_ERR "%s: DMA read error\n", drive->name); - ide_dma_off(drive); - } - } - - if (cdrom_decode_status(drive, 0, )) - return ide_stopped; - - if (dma) { - if (!dma_error) { - ide_end_request(drive, 1, rq->nr_sectors); - return ide_stopped; - } else - return ide_error(drive, "dma error", stat); - } - - /* Read the interrupt reason and the transfer length. */ - ireason = HWIF(drive)->INB(IDE_IREASON_REG) & 0x3; - lowcyl = HWIF(drive)->INB(IDE_BCOUNTL_REG); - highcyl = HWIF(drive)->INB(IDE_BCOUNTH_REG); - - len = lowcyl + (256 * highcyl); - - /* If DRQ is clear, the command has completed. */ - if ((stat & DRQ_STAT) == 0) { - /* If we're not done filling the current buffer, complain. - Otherwise, complete the command normally. */ - if (rq->current_nr_sectors > 0) { - printk (KERN_ERR "%s: cdrom_read_intr: data underrun (%d blocks)\n", - drive->name, rq->current_nr_sectors); - rq->cmd_flags |= REQ_FAILED; - cdrom_end_request(drive, 0); - } else - cdrom_end_request(drive, 1); - return ide_stopped; - } - - /* Check that the drive is expecting to do the same thing we are. */ - if (cdrom_read_check_ireason (drive, len, ireason)) - return ide_stopped; - - if (ide_cd_check_transfer_size(drive, len)) { - cdrom_end_request(drive, 0); - return ide_stopped; - } - - /* The number of sectors we need to read from the drive. */ - sectors_to_transfer = len / SECTOR_SIZE; - - /* First, figure out if we need to bit-bucket - any of the leading sectors. */ - nskip = min_t(int, rq->current_nr_sectors - bio_cur_sectors(rq->bio), sectors_to_transfer); - - if (nskip > 0) { - ide_cd_drain_data(drive, nskip); - rq->current_nr_sectors -= nskip; - sectors_to_transfer -= nskip; - } - - /* Now loop while we still have data to read from the drive. */ - while (sectors_to_transfer > 0) { - int this_transfer; - - /* If we've filled the present buffer but there's another - chained buffer after it, move on. */ - if (rq->current_nr_sectors == 0 && rq->nr_sectors) - cdrom_end_request(drive, 1); - - /* If the buffers are full, cache the rest of the data in our - internal buffer. */ - if (rq->current_nr_sectors == 0) { - cdrom_buffer_sectors(drive, rq->sector, sectors_to_transfer); - sectors_to_transfer = 0; - } else { - /* Transfer data to the buffers. - Figure out how many sectors we can transfer - to the current buffer. */ - this_transfer = min_t(int, sectors_to_transfer, -rq->current_nr_sectors); - - /* Read this_transfer sectors - into the current buffer. */ - while (this_transfer > 0) { - HWIF(drive)->atapi_input_bytes(drive, rq->buffer, SECTOR_SIZE); - rq->buffer += SECTOR_SIZE; - --rq->nr_sectors; - --rq->current_nr_sectors; -
[PATCH 53/63] ide-cd: factor out transfer size checking from cdrom_read_intr()
This is a preparation for cdrom_read_intr() and cdrom_write_intr() merge. Signed-off-by: Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]> --- +26 bytes drivers/ide/ide-cd.c | 38 ++ 1 file changed, 26 insertions(+), 12 deletions(-) Index: b/drivers/ide/ide-cd.c === --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -714,6 +714,31 @@ int cdrom_read_check_ireason (ide_drive_ } /* + * Assume that the drive will always provide data in multiples of at least + * SECTOR_SIZE, as it gets hairy to keep track of the transfers otherwise. + */ +static int ide_cd_check_transfer_size(ide_drive_t *drive, int len) +{ + struct cdrom_info *cd = drive->driver_data; + + if ((len % SECTOR_SIZE) == 0) + return 0; + + printk(KERN_ERR "%s: %s: Bad transfer size %d\n", + drive->name, __FUNCTION__, len); + + if (cd->cd_flags & IDE_CD_FLAG_LIMIT_NFRAMES) + printk(KERN_ERR " This drive is not supported by " + "this version of the driver\n"); + else { + printk(KERN_ERR " Trying to limit transfer sizes\n"); + cd->cd_flags |= IDE_CD_FLAG_LIMIT_NFRAMES; + } + + return 1; +} + +/* * Interrupt routine. Called when a read request has completed. */ static ide_startstop_t cdrom_read_intr (ide_drive_t *drive) @@ -774,18 +799,7 @@ static ide_startstop_t cdrom_read_intr ( if (cdrom_read_check_ireason (drive, len, ireason)) return ide_stopped; - /* Assume that the drive will always provide data in multiples - of at least SECTOR_SIZE, as it gets hairy to keep track - of the transfers otherwise. */ - if ((len % SECTOR_SIZE) != 0) { - printk (KERN_ERR "%s: cdrom_read_intr: Bad transfer size %d\n", - drive->name, len); - if (info->cd_flags & IDE_CD_FLAG_LIMIT_NFRAMES) - printk (KERN_ERR " This drive is not supported by this version of the driver\n"); - else { - printk (KERN_ERR " Trying to limit transfer sizes\n"); - info->cd_flags |= IDE_CD_FLAG_LIMIT_NFRAMES; - } + if (ide_cd_check_transfer_size(drive, len)) { cdrom_end_request(drive, 0); return ide_stopped; } -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 56/63] ide-cd: merge cdrom_start_read() and cdrom_start_write()
Add handling of read requests to cdrom_start_write(), rename it to cdrom_start_rw() and remove no longer needed cdrom_start_read(). There should be no functionality changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]> --- -20 bytes drivers/ide/ide-cd.c | 101 --- 1 file changed, 40 insertions(+), 61 deletions(-) Index: b/drivers/ide/ide-cd.c === --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -918,38 +918,6 @@ static void restore_request (struct requ rq->q->prep_rq_fn(rq->q, rq); } -/* - * Start a read request from the CD-ROM. - */ -static ide_startstop_t cdrom_start_read (ide_drive_t *drive, unsigned int block) -{ - struct cdrom_info *info = drive->driver_data; - struct request *rq = HWGROUP(drive)->rq; - unsigned short sectors_per_frame; - - sectors_per_frame = queue_hardsect_size(drive->queue) >> SECTOR_BITS; - - /* We may be retrying this request after an error. Fix up - any weirdness which might be present in the request packet. */ - restore_request(rq); - - /* Satisfy whatever we can of this request from our cached sector. */ - if (cdrom_read_from_buffer(drive)) - return ide_stopped; - - /* Clear the local sector buffer. */ - info->nsectors_buffered = 0; - - /* use dma, if possible. */ - info->dma = drive->using_dma; - if ((rq->sector & (sectors_per_frame - 1)) || - (rq->nr_sectors & (sectors_per_frame - 1))) - info->dma = 0; - - /* Start sending the read request to the drive. */ - return cdrom_start_packet_command(drive, 32768, cdrom_start_rw_cont); -} - / * Execute all other packet commands. */ @@ -1368,38 +1336,53 @@ static ide_startstop_t cdrom_rw_intr(ide return ide_started; } -static ide_startstop_t cdrom_start_write(ide_drive_t *drive, struct request *rq) +static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq) { - struct cdrom_info *info = drive->driver_data; - struct gendisk *g = info->disk; - unsigned short sectors_per_frame = queue_hardsect_size(drive->queue) >> SECTOR_BITS; + struct cdrom_info *cd = drive->driver_data; + int write = rq_data_dir(rq) == WRITE; + unsigned short sectors_per_frame = + queue_hardsect_size(drive->queue) >> SECTOR_BITS; - /* -* writes *must* be hardware frame aligned -*/ - if ((rq->nr_sectors & (sectors_per_frame - 1)) || - (rq->sector & (sectors_per_frame - 1))) { - cdrom_end_request(drive, 0); - return ide_stopped; + if (write) { + /* +* disk has become write protected +*/ + if (cd->disk->policy) { + cdrom_end_request(drive, 0); + return ide_stopped; + } + } else { + /* +* We may be retrying this request after an error. Fix up any +* weirdness which might be present in the request packet. +*/ + restore_request(rq); + + /* Satisfy whatever we can of this request from our cache. */ + if (cdrom_read_from_buffer(drive)) + return ide_stopped; } /* -* disk has become write protected +* use DMA, if possible / writes *must* be hardware frame aligned */ - if (g->policy) { - cdrom_end_request(drive, 0); - return ide_stopped; - } - - info->nsectors_buffered = 0; + if ((rq->nr_sectors & (sectors_per_frame - 1)) || + (rq->sector & (sectors_per_frame - 1))) { + if (write) { + cdrom_end_request(drive, 0); + return ide_stopped; + } + cd->dma = 0; + } else + cd->dma = drive->using_dma; - /* use dma, if possible. we don't need to check more, since we -* know that the transfer is always (at least!) frame aligned */ - info->dma = drive->using_dma ? 1 : 0; + /* Clear the local sector buffer. */ + cd->nsectors_buffered = 0; - info->devinfo.media_written = 1; + if (write) + cd->devinfo.media_written = 1; - /* Start sending the write request to the drive. */ + /* Start sending the read/write request to the drive. */ return cdrom_start_packet_command(drive, 32768, cdrom_start_rw_cont); } @@ -1472,12 +1455,8 @@ ide_do_rw_cdrom (ide_drive_t *drive, str } if ((rq_data_dir(rq) == READ) && IDE_LARGE_SEEK(info->last_block, block, IDECD_SEEK_THRESHOLD) && drive->dsc_overlap)
[PATCH 55/63] ide-cd: merge cdrom_start_read_continuation() and cdrom_start_rw_cont()
* Add handling of write requests to cdrom_start_read_continuation(), rename it to cdrom_start_rw_cont() and remove no longer needed cdrom_start_write_cont(). * Remove redundant '(rq->sector & (sectors_per_frame - 1)' check. There should be no functionality changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]> --- -51 bytes drivers/ide/ide-cd.c | 74 --- 1 file changed, 35 insertions(+), 39 deletions(-) Index: b/drivers/ide/ide-cd.c === --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -800,39 +800,48 @@ static int cdrom_read_from_buffer (ide_d static ide_startstop_t cdrom_rw_intr(ide_drive_t *); /* - * Routine to send a read packet command to the drive. - * This is usually called directly from cdrom_start_read. + * Routine to send a read/write packet command to the drive. + * This is usually called directly from cdrom_start_{read,write}(). * However, for drq_interrupt devices, it is called from an interrupt * when the drive is ready to accept the command. */ -static ide_startstop_t cdrom_start_read_continuation (ide_drive_t *drive) +static ide_startstop_t cdrom_start_rw_cont(ide_drive_t *drive) { struct request *rq = HWGROUP(drive)->rq; - unsigned short sectors_per_frame; - int nskip; - sectors_per_frame = queue_hardsect_size(drive->queue) >> SECTOR_BITS; + if (rq_data_dir(rq) == READ) { + unsigned short sectors_per_frame = + queue_hardsect_size(drive->queue) >> SECTOR_BITS; + int nskip = rq->sector & (sectors_per_frame - 1); - /* If the requested sector doesn't start on a cdrom block boundary, - we must adjust the start of the transfer so that it does, - and remember to skip the first few sectors. - If the CURRENT_NR_SECTORS field is larger than the size - of the buffer, it will mean that we're to skip a number - of sectors equal to the amount by which CURRENT_NR_SECTORS - is larger than the buffer size. */ - nskip = rq->sector & (sectors_per_frame - 1); - if (nskip > 0) { - /* Sanity check... */ - if (rq->current_nr_sectors != bio_cur_sectors(rq->bio) && - (rq->sector & (sectors_per_frame - 1))) { - printk(KERN_ERR "%s: cdrom_start_read_continuation: buffer botch (%u)\n", - drive->name, rq->current_nr_sectors); - cdrom_end_request(drive, 0); - return ide_stopped; + /* +* If the requested sector doesn't start on a frame boundary, +* we must adjust the start of the transfer so that it does, +* and remember to skip the first few sectors. +* +* If the rq->current_nr_sectors field is larger than the size +* of the buffer, it will mean that we're to skip a number of +* sectors equal to the amount by which rq->current_nr_sectors +* is larger than the buffer size. +*/ + if (nskip > 0) { + /* Sanity check... */ + if (rq->current_nr_sectors != + bio_cur_sectors(rq->bio)) { + printk(KERN_ERR "%s: %s: buffer botch (%u)\n", + drive->name, __FUNCTION__, + rq->current_nr_sectors); + cdrom_end_request(drive, 0); + return ide_stopped; + } + rq->current_nr_sectors += nskip; } - rq->current_nr_sectors += nskip; } - +#if 0 + else + /* the immediate bit */ + rq->cmd[1] = 1 << 3; +#endif /* Set up the command */ rq->timeout = ATAPI_WAIT_PC; @@ -840,7 +849,6 @@ static ide_startstop_t cdrom_start_read_ return cdrom_transfer_packet_command(drive, rq, cdrom_rw_intr); } - #define IDECD_SEEK_THRESHOLD (1000) /* 1000 blocks */ #define IDECD_SEEK_TIMER (5 * WAIT_MIN_SLEEP)/* 100 ms */ #define IDECD_SEEK_TIMEOUT (2 * WAIT_CMD) /* 20 sec */ @@ -939,7 +947,7 @@ static ide_startstop_t cdrom_start_read info->dma = 0; /* Start sending the read request to the drive. */ - return cdrom_start_packet_command(drive, 32768, cdrom_start_read_continuation); + return cdrom_start_packet_command(drive, 32768, cdrom_start_rw_cont); } / @@ -1360,18 +1368,6 @@ static ide_startstop_t cdrom_rw_intr(ide return ide_started; } -static ide_startstop_t
[PATCH 58/63] ide-cd: prepare cdrom_rw_intr() and cdrom_newpc_intr() to be merged
In cdrom_newpc_intr(): * cleanup variables in the 'transfer data' loop In cdrom_rw_intr(): * rename 'sectors_to_transfer' to 'thislen' * rename 'this_transfer' to 'blen' * keep number of bytes (instead of sectors) in 'thislen' and 'blen' * call 'xferfunc' only once for 'blen' * cache 'rq->buffer' in 'ptr' variable * check for 'rq->bio' before setting 'ptr' and 'blen' * check for 'ptr' instead of 'rq->current_nr_sectors' There should be no functionality changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]> --- +54 bytes drivers/ide/ide-cd.c | 45 + 1 file changed, 25 insertions(+), 20 deletions(-) Index: b/drivers/ide/ide-cd.c === --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -1115,8 +1115,8 @@ static ide_startstop_t cdrom_newpc_intr( * transfer data */ while (thislen > 0) { - int blen = blen = rq->data_len; - char *ptr = rq->data; + u8 *ptr = rq->data; + int blen = rq->data_len; /* * bio backed? @@ -1192,7 +1192,7 @@ static ide_startstop_t cdrom_rw_intr(ide struct cdrom_info *info = drive->driver_data; struct request *rq = HWGROUP(drive)->rq; xfer_func_t *xferfunc; - int stat, ireason, len, sectors_to_transfer, uptodate, nskip; + int stat, ireason, len, thislen, uptodate, nskip; int dma_error = 0, dma = info->dma, write = rq_data_dir(rq) == WRITE; u8 lowcyl = 0, highcyl = 0; @@ -1247,7 +1247,7 @@ static ide_startstop_t cdrom_rw_intr(ide return ide_stopped; } - sectors_to_transfer = len / SECTOR_SIZE; + thislen = len; /* Check that the drive is expecting to do the same thing we are. */ if (write) { @@ -1270,12 +1270,12 @@ static ide_startstop_t cdrom_rw_intr(ide */ nskip = min_t(int, rq->current_nr_sectors - bio_cur_sectors(rq->bio), - sectors_to_transfer); + thislen >> 9); if (nskip > 0) { ide_cd_drain_data(drive, nskip); rq->current_nr_sectors -= nskip; - sectors_to_transfer -= nskip; + thislen -= (nskip << 9); } xferfunc = HWIF(drive)->atapi_input_bytes; @@ -1284,17 +1284,23 @@ static ide_startstop_t cdrom_rw_intr(ide /* * now loop and read/write the data */ - while (sectors_to_transfer > 0) { - int this_transfer; + while (thislen > 0) { + u8 *ptr = NULL; + int blen; + + if (rq->bio) { + ptr = rq->buffer; + blen = rq->current_nr_sectors << 9; + } - if (!rq->current_nr_sectors) { + if (!ptr) { if (!write) /* * If the buffers are full, cache the rest * of the data in our internal buffer. */ cdrom_buffer_sectors(drive, rq->sector, -sectors_to_transfer); +thislen >> 9); else printk(KERN_ERR "%s: %s: confused, missing " "data\n", @@ -1305,17 +1311,16 @@ static ide_startstop_t cdrom_rw_intr(ide /* * Figure out how many sectors we can transfer */ - this_transfer = min_t(int, sectors_to_transfer, rq->current_nr_sectors); + if (blen > thislen) + blen = thislen; - while (this_transfer > 0) { - xferfunc(drive, rq->buffer, SECTOR_SIZE); - rq->buffer += SECTOR_SIZE; - --rq->nr_sectors; - --rq->current_nr_sectors; - ++rq->sector; - --this_transfer; - --sectors_to_transfer; - } + xferfunc(drive, ptr, blen); + + thislen -= blen; + rq->buffer += blen; + rq->nr_sectors -= (blen >> 9); + rq->current_nr_sectors -= (blen >> 9); + rq->sector += (blen >> 9); /* * current buffer complete, move on -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at
[PATCH 57/63] ide-cd: unify moving to the next buffer in cdrom_rw_intr()
Use the fact that for the first loop rq->current_nr_sectors is always set and unify moving to the next buffer for read/write requests. There should be no functionality changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]> --- -46 bytes drivers/ide/ide-cd.c |9 + 1 file changed, 1 insertion(+), 8 deletions(-) Index: b/drivers/ide/ide-cd.c === --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -1287,13 +1287,6 @@ static ide_startstop_t cdrom_rw_intr(ide while (sectors_to_transfer > 0) { int this_transfer; - /* -* If we've filled the present buffer but there's another -* chained buffer after it, move on. -*/ - if (!write && rq->current_nr_sectors == 0 && rq->nr_sectors) - cdrom_end_request(drive, 1); - if (!rq->current_nr_sectors) { if (!write) /* @@ -1327,7 +1320,7 @@ static ide_startstop_t cdrom_rw_intr(ide /* * current buffer complete, move on */ - if (write && rq->current_nr_sectors == 0 && rq->nr_sectors) + if (rq->current_nr_sectors == 0 && rq->nr_sectors) cdrom_end_request(drive, 1); } -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 60/63] ide-cd: merge cdrom_rw_intr() and cdrom_newpc_intr()
Add handling of fs read/write requests to cdrom_nepwc_intr() and remove no longer needed cdrom_rw_intr(). There should be no functionality changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]> --- -496 bytes drivers/ide/ide-cd.c | 272 +-- 1 file changed, 94 insertions(+), 178 deletions(-) Index: b/drivers/ide/ide-cd.c === --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -797,7 +797,7 @@ static int cdrom_read_from_buffer (ide_d return 0; } -static ide_startstop_t cdrom_rw_intr(ide_drive_t *); +static ide_startstop_t cdrom_newpc_intr(ide_drive_t *); /* * Routine to send a read/write packet command to the drive. @@ -846,7 +846,7 @@ static ide_startstop_t cdrom_start_rw_co rq->timeout = ATAPI_WAIT_PC; /* Send the command to the drive and return. */ - return cdrom_transfer_packet_command(drive, rq, cdrom_rw_intr); + return cdrom_transfer_packet_command(drive, rq, cdrom_newpc_intr); } #define IDECD_SEEK_THRESHOLD (1000) /* 1000 blocks */ @@ -1013,17 +1013,12 @@ static int cdrom_write_check_ireason(ide return 1; } -/* - * best way to deal with dma that is not sector aligned right now... note - * that in this path we are not using ->data or ->buffer at all. this irs - * can replace cdrom_rw_intr() in the future. - */ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) { struct cdrom_info *info = drive->driver_data; struct request *rq = HWGROUP(drive)->rq; xfer_func_t *xferfunc; - ide_expiry_t *expiry; + ide_expiry_t *expiry = NULL; int dma_error = 0, dma, stat, ireason, len, thislen, uptodate = 0; int write = (rq_data_dir(rq) == WRITE) ? 1 : 0; unsigned int timeout; @@ -1051,6 +1046,10 @@ static ide_startstop_t cdrom_newpc_intr( if (dma_error) return ide_error(drive, "dma error", stat); + if (blk_fs_request(rq)) { + ide_end_request(drive, 1, rq->nr_sectors); + return ide_stopped; + } end_that_request_chunk(rq, 1, rq->data_len); rq->data_len = 0; goto end_request; @@ -1064,7 +1063,8 @@ static ide_startstop_t cdrom_newpc_intr( highcyl = HWIF(drive)->INB(IDE_BCOUNTH_REG); len = lowcyl + (256 * highcyl); - thislen = rq->data_len; + + thislen = blk_fs_request(rq) ? len : rq->data_len; if (thislen > len) thislen = len; @@ -1072,7 +1072,24 @@ static ide_startstop_t cdrom_newpc_intr( * If DRQ is clear, the command has completed. */ if ((stat & DRQ_STAT) == 0) { - if (!blk_pc_request(rq)) { + if (blk_fs_request(rq)) { + /* +* If we're not done reading/writing, complain. +* Otherwise, complete the command normally. +*/ + uptodate = 1; + if (rq->current_nr_sectors > 0) { + printk(KERN_ERR "%s: %s: data underrun " + "(%d blocks)\n", + drive->name, __FUNCTION__, + rq->current_nr_sectors); + if (!write) + rq->cmd_flags |= REQ_FAILED; + uptodate = 0; + } + cdrom_end_request(drive, uptodate); + return ide_stopped; + } else if (!blk_pc_request(rq)) { ide_cd_request_sense_fixup(rq); /* Complain if we still have data left to transfer. */ uptodate = rq->data_len ? 0 : 1; @@ -1083,24 +1100,47 @@ static ide_startstop_t cdrom_newpc_intr( /* * check which way to transfer data */ - if (blk_pc_request(rq) && rq_data_dir(rq) == WRITE) { + if ((blk_fs_request(rq) || blk_pc_request(rq)) && write) { /* * write to drive */ if (cdrom_write_check_ireason(drive, len, ireason)) return ide_stopped; - } else if (blk_pc_request(rq)) { + } else if (blk_fs_request(rq) || blk_pc_request(rq)) { /* * read from drive */ if (cdrom_read_check_ireason(drive, len, ireason)) return ide_stopped; + + if (blk_fs_request(rq)) { + int nskip; + + if (ide_cd_check_transfer_size(drive, len)) { + cdrom_end_request(drive, 0); +
[PATCH 59/63] ide-cd: call blk_dump_rq_flags() on "missing data" in cdrom_rw_intr()
Signed-off-by: Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]> --- drivers/ide/ide-cd.c |4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) Index: b/drivers/ide/ide-cd.c === --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -1301,10 +1301,12 @@ static ide_startstop_t cdrom_rw_intr(ide */ cdrom_buffer_sectors(drive, rq->sector, thislen >> 9); - else + else { printk(KERN_ERR "%s: %s: confused, missing " "data\n", drive->name, __FUNCTION__); + blk_dump_rq_flags(rq, "cdrom_rw_intr, write"); + } break; } -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 62/63] ide-cd: unify request end exit path in cdrom_decode_status()
There should be no functionality changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]> --- -59 bytes drivers/ide/ide-cd.c | 50 -- 1 file changed, 24 insertions(+), 26 deletions(-) Index: b/drivers/ide/ide-cd.c === --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -332,7 +332,6 @@ static int cdrom_decode_status(ide_drive } else if (blk_pc_request(rq) || rq->cmd_type == REQ_TYPE_ATA_PC) { /* All other functions, except for READ. */ - unsigned long flags; /* * if we have an error, pass back CHECK_CONDITION as the @@ -370,15 +369,7 @@ static int cdrom_decode_status(ide_drive * remove failed request completely and end it when the * request sense has completed */ - if (stat & ERR_STAT) { - spin_lock_irqsave(_lock, flags); - blkdev_dequeue_request(rq); - HWGROUP(drive)->rq = NULL; - spin_unlock_irqrestore(_lock, flags); - - cdrom_queue_request_sense(drive, rq->sense, rq); - } else - cdrom_end_request(drive, 0); + goto end_request; } else if (blk_fs_request(rq)) { int do_end_request = 0; @@ -458,23 +449,15 @@ static int cdrom_decode_status(ide_drive sense data. We need this in order to perform end of media processing */ - if (do_end_request) { - if (stat & ERR_STAT) { - unsigned long flags; - spin_lock_irqsave(_lock, flags); - blkdev_dequeue_request(rq); - HWGROUP(drive)->rq = NULL; - spin_unlock_irqrestore(_lock, flags); + if (do_end_request) + goto end_request; - cdrom_queue_request_sense(drive, rq->sense, rq); - } else - cdrom_end_request(drive, 0); - } else { - /* If we got a CHECK_CONDITION status, - queue a request sense command. */ - if (stat & ERR_STAT) - cdrom_queue_request_sense(drive, NULL, NULL); - } + /* +* If we got a CHECK_CONDITION status, +* queue a request sense command. +*/ + if (stat & ERR_STAT) + cdrom_queue_request_sense(drive, NULL, NULL); } else { blk_dump_rq_flags(rq, "ide-cd: bad rq"); cdrom_end_request(drive, 0); @@ -482,6 +465,21 @@ static int cdrom_decode_status(ide_drive /* Retry, or handle the next request. */ return 1; + +end_request: + if (stat & ERR_STAT) { + unsigned long flags; + + spin_lock_irqsave(_lock, flags); + blkdev_dequeue_request(rq); + HWGROUP(drive)->rq = NULL; + spin_unlock_irqrestore(_lock, flags); + + cdrom_queue_request_sense(drive, rq->sense, rq); + } else + cdrom_end_request(drive, 0); + + return 1; } static int cdrom_timer_expiry(ide_drive_t *drive) -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 61/63] ide-cd: merge cdrom_write_check_ireason() and cdrom_read_check_ireason()
Add 'rw' parameter to cdrom_read_check_ireason(), make it handle both read and write checking, rename it to ide_cd_check_ireason(), finally remove no longer needed cdrom_write_check_ireason(). There should be no functionality changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]> --- -61 bytes drivers/ide/ide-cd.c | 64 +++ 1 file changed, 15 insertions(+), 49 deletions(-) Index: b/drivers/ide/ide-cd.c === --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -683,21 +683,25 @@ static void cdrom_buffer_sectors (ide_dr * ok; nonzero if the request has been terminated. */ static -int cdrom_read_check_ireason (ide_drive_t *drive, int len, int ireason) +int ide_cd_check_ireason(ide_drive_t *drive, int len, int ireason, int rw) { - if (ireason == 2) + /* +* ireason == 0: the drive wants to receive data from us +* ireason == 2: the drive is expecting to transfer data to us +*/ + if (ireason == (!rw << 1)) return 0; - else if (ireason == 0) { + else if (ireason == (rw << 1)) { ide_hwif_t *hwif = drive->hwif; + xfer_func_t *xf; - /* Whoops... The drive is expecting to receive data from us! */ + /* Whoops... */ printk(KERN_ERR "%s: %s: wrong transfer direction!\n", drive->name, __FUNCTION__); - /* Throw some data at the drive so it doesn't hang - and quit this request. */ - ide_cd_pad_transfer(drive, hwif->atapi_output_bytes, len); - } else if (ireason == 1) { + xf = rw ? hwif->atapi_output_bytes : hwif->atapi_input_bytes; + ide_cd_pad_transfer(drive, xf, len); + } else if (rw == 0 && ireason == 1) { /* Some drives (ASUS) seem to tell us that status * info is available. just get it and ignore. */ @@ -984,35 +988,6 @@ int ide_cd_queue_pc(ide_drive_t *drive, return (rq->cmd_flags & REQ_FAILED) ? -EIO : 0; } -/* - * Write handling - */ -static int cdrom_write_check_ireason(ide_drive_t *drive, int len, int ireason) -{ - /* Two notes about IDE interrupt reason here - 0 means that -* the drive wants to receive data from us, 2 means that -* the drive is expecting to transfer data to us. -*/ - if (ireason == 0) - return 0; - else if (ireason == 2) { - ide_hwif_t *hwif = drive->hwif; - - /* Whoops... The drive wants to send data. */ - printk(KERN_ERR "%s: %s: wrong transfer direction!\n", - drive->name, __FUNCTION__); - - ide_cd_pad_transfer(drive, hwif->atapi_input_bytes, len); - } else { - /* Drive wants a command packet, or invalid ireason... */ - printk(KERN_ERR "%s: %s: bad interrupt reason 0x%02x\n", - drive->name, __FUNCTION__, ireason); - } - - cdrom_end_request(drive, 0); - return 1; -} - static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) { struct cdrom_info *info = drive->driver_data; @@ -1100,20 +1075,11 @@ static ide_startstop_t cdrom_newpc_intr( /* * check which way to transfer data */ - if ((blk_fs_request(rq) || blk_pc_request(rq)) && write) { - /* -* write to drive -*/ - if (cdrom_write_check_ireason(drive, len, ireason)) - return ide_stopped; - } else if (blk_fs_request(rq) || blk_pc_request(rq)) { - /* -* read from drive -*/ - if (cdrom_read_check_ireason(drive, len, ireason)) + if (blk_fs_request(rq) || blk_pc_request(rq)) { + if (ide_cd_check_ireason(drive, len, ireason, write)) return ide_stopped; - if (blk_fs_request(rq)) { + if (blk_fs_request(rq) && write == 0) { int nskip; if (ide_cd_check_transfer_size(drive, len)) { -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 63/63] ide-cd: update driver version, comments and copyrights
* Bump driver version. * Remove filename and stale TODO from comments. * Add my copyrights. Signed-off-by: Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]> --- drivers/ide/ide-cd.c | 17 - 1 file changed, 4 insertions(+), 13 deletions(-) Index: b/drivers/ide/ide-cd.c === --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -1,14 +1,14 @@ /* - * linux/drivers/ide/ide-cd.c + * ATAPI CD-ROM driver. * - * Copyright (C) 1994, 1995, 1996 scott snyder <[EMAIL PROTECTED]> + * Copyright (C) 1994-1996 Scott Snyder <[EMAIL PROTECTED]> * Copyright (C) 1996-1998 Erik Andersen <[EMAIL PROTECTED]> * Copyright (C) 1998-2000 Jens Axboe <[EMAIL PROTECTED]> + * Copyright (C) 2007 Bartlomiej Zolnierkiewicz * * May be copied or modified under the terms of the GNU General Public * License. See linux/COPYING for more information. * - * ATAPI CD-ROM driver. To be used with ide.c. * See Documentation/cdrom/ide-cd for usage information. * * Suggestions are welcome. Patches that work are more welcome though. ;-) @@ -19,20 +19,11 @@ * ftp://fission.dt.wdc.com/pub/standards/SFF_atapi/spec/SFF8020-r2.6/PS/8020r26.ps * ftp://ftp.avc-pioneer.com/Mtfuji4/Spec/Fuji4r10.pdf * - * Drives that deviate from these standards will be accommodated as much - * as possible via compile time or command-line options. Since I only have - * a few drives, you generally need to send me patches... - * - * -- - * TO DO LIST: - * -Make it so that Pioneer CD DR-A24X and friends don't get screwed up on - * boot - * * For historical changelog please see: * Documentation/ide/ChangeLog.ide-cd.1994-2004 */ -#define IDECD_VERSION "4.61" +#define IDECD_VERSION "5.00" #include #include -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 38/63] ide-cd: merge cdrom_play_audio() into ide_cd_fake_play_trkind()
Signed-off-by: Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]> --- drivers/ide/ide-cd.c | 26 ++ 1 file changed, 10 insertions(+), 16 deletions(-) Index: b/drivers/ide/ide-cd.c === --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -2047,21 +2047,6 @@ static int cdrom_select_speed(ide_drive_ return cdrom_queue_packet_command(drive, ); } -static int cdrom_play_audio(ide_drive_t *drive, int lba_start, int lba_end) -{ - struct request_sense sense; - struct request req; - - cdrom_prepare_request(drive, ); - - req.sense = - req.cmd[0] = GPCMD_PLAY_AUDIO_MSF; - lba_to_msf(lba_start, [3], [4], [5]); - lba_to_msf(lba_end-1, [6], [7], [8]); - - return cdrom_queue_packet_command(drive, ); -} - static int cdrom_get_toc_entry(ide_drive_t *drive, int track, struct atapi_toc_entry **ent) { @@ -2118,6 +2103,8 @@ static int ide_cd_fake_play_trkind(ide_d struct atapi_toc_entry *first_toc, *last_toc; unsigned long lba_start, lba_end; int stat; + struct request rq; + struct request_sense sense; stat = cdrom_get_toc_entry(drive, ti->cdti_trk0, _toc); if (stat) @@ -2135,7 +2122,14 @@ static int ide_cd_fake_play_trkind(ide_d if (lba_end <= lba_start) return -EINVAL; - return cdrom_play_audio(drive, lba_start, lba_end); + cdrom_prepare_request(drive, ); + + rq.sense = + rq.cmd[0] = GPCMD_PLAY_AUDIO_MSF; + lba_to_msf(lba_start, [3], [4], [5]); + lba_to_msf(lba_end - 1, [6], [7], [8]); + + return cdrom_queue_packet_command(drive, ); } /* the generic packet interface to cdrom.c */ -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 48/63] ide-cd: unify request end exit path in cdrom_pc_intr()
This is a preparation for cdrom_pc_intr() and cdrom_newpc_intr() merge. Signed-off-by: Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]> --- +10 bytes drivers/ide/ide-cd.c | 23 +++ 1 file changed, 11 insertions(+), 12 deletions(-) Index: b/drivers/ide/ide-cd.c === --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -1066,7 +1066,7 @@ static ide_startstop_t cdrom_pc_intr (id { struct request *rq = HWGROUP(drive)->rq; xfer_func_t *xferfunc = NULL; - int stat, ireason, len, thislen, write; + int stat, ireason, len, thislen, write, update; u8 lowcyl = 0, highcyl = 0; /* Check for errors. */ @@ -1084,14 +1084,8 @@ static ide_startstop_t cdrom_pc_intr (id Complain if we still have data left to transfer. */ if ((stat & DRQ_STAT) == 0) { ide_cd_request_sense_fixup(rq); - - if (rq->data_len == 0) - cdrom_end_request(drive, 1); - else { - rq->cmd_flags |= REQ_FAILED; - cdrom_end_request(drive, 0); - } - return ide_stopped; + update = rq->data_len ? 0 : 1; + goto end_request; } /* Figure out how much data to transfer. */ @@ -1130,9 +1124,8 @@ static ide_startstop_t cdrom_pc_intr (id "appears confused (ireason = 0x%02x). " "Trying to recover by ending request.\n", drive->name, ireason); - rq->cmd_flags |= REQ_FAILED; - cdrom_end_request(drive, 0); - return ide_stopped; + update = 0; + goto end_request; } pad: /* @@ -1145,6 +1138,12 @@ pad: /* Now we wait for another interrupt. */ ide_set_handler(drive, _pc_intr, ATAPI_WAIT_PC, cdrom_timer_expiry); return ide_started; + +end_request: + if (!update) + rq->cmd_flags |= REQ_FAILED; + cdrom_end_request(drive, update); + return ide_stopped; } static ide_startstop_t cdrom_do_pc_continuation (ide_drive_t *drive) -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 36/63] ide-cd: move VERBOSE_IDE_CD_ERRORS code to ide-cd_verbose.c
* Rename ide-cd kernel module to ide-cd_mod in preparation to moving code out from ide-cd.[c,h]. Add MODULE_ALIAS("ide-cd") to preserve compatibility. * Move VERBOSE_IDE_CD_ERRORS code from ide-cd.[c,h] to ide-cd_verbose.c. ide-cd_verbose.c is IDE subsystem independent and may be easily converted into generic library usable by other drivers (i.e. libata) if needed. * Add CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS config option to drivers/ide/Kconfig replacing VERBOSE_IDE_CD_ERRORS define. Make this config option enabled by default and visible only if CONFIG_EMBEDDED is defined. before the patch: textdata bss dec hex filename 22841 3601056 242575ec1 drivers/ide/ide-cd.o after the patch w/ CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y: textdata bss dec hex filename 22857 3601056 242735ed1 drivers/ide/ide-cd_mod.o after the patch w/ CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=n: textdata bss dec hex filename 15091 3601056 16507407b drivers/ide/ide-cd_mod.o Signed-off-by: Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]> --- drivers/ide/Kconfig |9 + drivers/ide/Makefile |4 drivers/ide/ide-cd.c | 124 -- drivers/ide/ide-cd.h | 237 drivers/ide/ide-cd_verbose.c | 359 +++ 5 files changed, 375 insertions(+), 358 deletions(-) Index: b/drivers/ide/Kconfig === --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -206,6 +206,15 @@ config BLK_DEV_IDECD To compile this driver as a module, choose M here: the module will be called ide-cd. +config BLK_DEV_IDECD_VERBOSE_ERRORS + bool "Verbose error logging for IDE/ATAPI CDROM driver" if EMBEDDED + depends on BLK_DEV_IDECD + default y + help + Turn this on to have the driver print out the meanings of the + ATAPI error codes. This will use up additional 8kB of kernel-space + memory, though. + config BLK_DEV_IDETAPE tristate "Include IDE/ATAPI TAPE support (EXPERIMENTAL)" depends on EXPERIMENTAL Index: b/drivers/ide/Makefile === --- a/drivers/ide/Makefile +++ b/drivers/ide/Makefile @@ -40,8 +40,10 @@ obj-$(CONFIG_BLK_DEV_IDEPNP) += ide-pnp obj-$(CONFIG_IDE_H8300)+= h8300/ obj-$(CONFIG_IDE_GENERIC) += ide-generic.o +ide-cd_mod-y += ide-cd.o ide-cd_verbose.o + obj-$(CONFIG_BLK_DEV_IDEDISK) += ide-disk.o -obj-$(CONFIG_BLK_DEV_IDECD)+= ide-cd.o +obj-$(CONFIG_BLK_DEV_IDECD)+= ide-cd_mod.o obj-$(CONFIG_BLK_DEV_IDETAPE) += ide-tape.o obj-$(CONFIG_BLK_DEV_IDEFLOPPY)+= ide-floppy.o Index: b/drivers/ide/ide-cd.c === --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -199,129 +199,8 @@ void cdrom_analyze_sense_data(ide_drive_ } } } -#if VERBOSE_IDE_CD_ERRORS - { - int i; - const char *s = "bad sense key!"; - char buf[80]; - - printk(KERN_ERR "ATAPI device %s:\n", drive->name); - if (sense->error_code == 0x70) - printk(KERN_CONT " Error: "); - else if (sense->error_code == 0x71) - printk(" Deferred Error: "); - else if (sense->error_code == 0x7f) - printk(KERN_CONT " Vendor-specific Error: "); - else - printk(KERN_CONT " Unknown Error Type: "); - - if (sense->sense_key < ARRAY_SIZE(sense_key_texts)) - s = sense_key_texts[sense->sense_key]; - - printk(KERN_CONT "%s -- (Sense key=0x%02x)\n", -s, sense->sense_key); - - if (sense->asc == 0x40) { - sprintf(buf, "Diagnostic failure on component 0x%02x", - sense->ascq); - s = buf; - } else { - int lo = 0, mid, hi = ARRAY_SIZE(sense_data_texts); - unsigned long key = (sense->sense_key << 16); - - key |= (sense->asc << 8); - if (!(sense->ascq >= 0x80 && sense->ascq <= 0xdd)) - key |= sense->ascq; - s = NULL; - - while (hi > lo) { - mid = (lo + hi) / 2; - if (sense_data_texts[mid].asc_ascq == key || - sense_data_texts[mid].asc_ascq == (0xff|key)) { - s = sense_data_texts[mid].text; -
[PATCH 34/63] ide-cd: remove duplicate sense keys definitions from ide-cd.h
ide-cd.c already uses sense keys definitions from . Signed-off-by: Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]> --- drivers/ide/ide-cd.h | 17 - 1 file changed, 17 deletions(-) Index: b/drivers/ide/ide-cd.h === --- a/drivers/ide/ide-cd.h +++ b/drivers/ide/ide-cd.h @@ -158,23 +158,6 @@ struct cdrom_info { */ /* This stuff should be in cdrom.h, since it is now generic... */ - -/* ATAPI sense keys (from table 140 of ATAPI 2.6) */ -#define NO_SENSE0x00 -#define RECOVERED_ERROR 0x01 -#define NOT_READY 0x02 -#define MEDIUM_ERROR0x03 -#define HARDWARE_ERROR 0x04 -#define ILLEGAL_REQUEST 0x05 -#define UNIT_ATTENTION 0x06 -#define DATA_PROTECT0x07 -#define BLANK_CHECK 0x08 -#define ABORTED_COMMAND 0x0b -#define MISCOMPARE 0x0e - - - -/* This stuff should be in cdrom.h, since it is now generic... */ #if VERBOSE_IDE_CD_ERRORS /* The generic packet command opcodes for CD/DVD Logical Units, -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 35/63] ide-cd: coding style fixes for VERBOSE_IDE_CD_ERRORS code
* Coding style fixes for VERBOSE_IDE_CD_ERRORS code. * Add KERN_{ERR,CONT} printk() levels where needed. This is a preparation for moving this code out of ide-cd.[c,h]. Signed-off-by: Bartlomiej Zolnierkiewicz <[EMAIL PROTECTED]> --- drivers/ide/ide-cd.c | 65 +-- drivers/ide/ide-cd.h | 33 - 2 files changed, 49 insertions(+), 49 deletions(-) Index: b/drivers/ide/ide-cd.c === --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -205,28 +205,30 @@ void cdrom_analyze_sense_data(ide_drive_ const char *s = "bad sense key!"; char buf[80]; - printk ("ATAPI device %s:\n", drive->name); - if (sense->error_code==0x70) - printk(" Error: "); - else if (sense->error_code==0x71) + printk(KERN_ERR "ATAPI device %s:\n", drive->name); + if (sense->error_code == 0x70) + printk(KERN_CONT " Error: "); + else if (sense->error_code == 0x71) printk(" Deferred Error: "); else if (sense->error_code == 0x7f) - printk(" Vendor-specific Error: "); + printk(KERN_CONT " Vendor-specific Error: "); else - printk(" Unknown Error Type: "); + printk(KERN_CONT " Unknown Error Type: "); if (sense->sense_key < ARRAY_SIZE(sense_key_texts)) s = sense_key_texts[sense->sense_key]; - printk("%s -- (Sense key=0x%02x)\n", s, sense->sense_key); + printk(KERN_CONT "%s -- (Sense key=0x%02x)\n", +s, sense->sense_key); if (sense->asc == 0x40) { sprintf(buf, "Diagnostic failure on component 0x%02x", -sense->ascq); + sense->ascq); s = buf; } else { int lo = 0, mid, hi = ARRAY_SIZE(sense_data_texts); unsigned long key = (sense->sense_key << 16); + key |= (sense->asc << 8); if (!(sense->ascq >= 0x80 && sense->ascq <= 0xdd)) key |= sense->ascq; @@ -238,11 +240,10 @@ void cdrom_analyze_sense_data(ide_drive_ sense_data_texts[mid].asc_ascq == (0xff|key)) { s = sense_data_texts[mid].text; break; - } - else if (sense_data_texts[mid].asc_ascq > key) + } else if (sense_data_texts[mid].asc_ascq > key) hi = mid; else - lo = mid+1; + lo = mid + 1; } } @@ -254,11 +255,10 @@ void cdrom_analyze_sense_data(ide_drive_ } printk(KERN_ERR " %s -- (asc=0x%02x, ascq=0x%02x)\n", - s, sense->asc, sense->ascq); + s, sense->asc, sense->ascq); if (failed_command != NULL) { - - int lo=0, mid, hi= ARRAY_SIZE(packet_command_texts); + int lo = 0, mid, hi = ARRAY_SIZE(packet_command_texts); s = NULL; while (hi > lo) { @@ -272,13 +272,15 @@ void cdrom_analyze_sense_data(ide_drive_ failed_command->cmd[0]) hi = mid; else - lo = mid+1; + lo = mid + 1; } - printk (KERN_ERR " The failed \"%s\" packet command was: \n \"", s); - for (i=0; icmd); i++) - printk ("%02x ", failed_command->cmd[i]); - printk ("\"\n"); + printk(KERN_ERR " The failed \"%s\" packet command " + "was: \n \"", s); + for (i = 0; i < sizeof(failed_command->cmd); i++) + printk(KERN_CONT "%02x ", +failed_command->cmd[i]); + printk(KERN_CONT "\"\n"); } /* The SKSV bit specifies validity of the sense_key_specific @@ -288,38 +290,37 @@ void cdrom_analyze_sense_data(ide_drive_ */ if (sense->sense_key == NOT_READY && (sense->sks[0] & 0x80)) { int