diff -ur linux-109/drivers/scsi/ultrastor.c linux/drivers/scsi/ultrastor.c --- linux-109/drivers/scsi/ultrastor.c Mon Jan 24 18:55:21 1994 +++ linux/drivers/scsi/ultrastor.c Sun Feb 15 12:46:24 1998 @@ -282,23 +282,29 @@ static inline int find_and_clear_bit_16(unsigned short *field) { int rv; + unsigned long flags; + + save_flags(flags); cli(); if (*field == 0) panic("No free mscp"); asm("xorl %0,%0\n0:\tbsfw %1,%w0\n\tbtr %0,%1\n\tjnc 0b" : "=&r" (rv), "=m" (*field) : "1" (*field)); - sti(); + restore_flags(flags); return rv; } -/* This asm is fragile: it doesn't work without the casts and it may +/* This has been re-implemented with the help of Richard Earnshaw, + and works with gcc-2.5.8 and gcc-2.6.0. + The instability noted by jfc below appears to be a bug in + gcc-2.5.x when compiling w/o optimization. --Caleb + + This asm is fragile: it doesn't work without the casts and it may not work without optimization. Maybe I should add a swap builtin to gcc. --jfc */ static inline unsigned char xchgb(unsigned char reg, volatile unsigned char *mem) { - asm("xchgb %0,%1" : - "=r" (reg), "=m" (*(unsigned char *)mem) : - "0" (reg), "1" (*(unsigned char *)mem)); + __asm__ ("xchgb %0,%1" : "=q" (reg), "=m" (*mem) : "0" (reg)); return reg; }