1) Defconstant doesn't really make sense in a function. It defines a global constant, which is constant. If you ever call the function again, you either provide the same (eql) value and have no effect, or a different value, which is illegal.
2) As you observed, the inner call doesn't know anything about the outer environment except what is passed as an argument. You can either keep it at that and add the remaining part after the return of the inner call (I elide checking the inputs in the following, you'd need to make sure that x is always a nonnegative integer):
(defun odd-range (x)
(cond ((zerop x) ())
((evenp x) (odd-range (1- x)))
(t (cons x
(append (odd-range (1- x))
(list (- x)))))))
Or you can pass the end number along as an additional argument:
(defun odd-range (start end)
(cond ((< start end) ())
((evenp start) (odd-range (1- start) end))
(t (cons start
(odd-range (1- start) end)))))
This would have the benefit of giving the caller free choice of the range as long as end is smaller than start.
You can also pass along the constructed list so far (often called an accumulator, abbreviated acc):
(defun odd-range (start end acc)
(cond ((< start end) (reverse acc))
((evenp start) (odd-range (1- start) end acc))
(t (odd-range (1- start) end (cons start acc)))))
This conses to the front of the list while accumulating and only reverses the result at the end. This avoids walking the accumulated list at every step and is a big improvement on running time. It also moves the recursive call into tail position so that the compiler may produce code that is equivalent to a simple loop, avoiding stack limits. This compiler technique is called tail call elimination or tail call optimization (TCO).
Since Common Lisp compilers are not required to do TCO, it is good style to write loops actually as loops. Examples:
(defun odd-range (start)
(do ((x start (1- x))
(end (- start))
(acc ()
(if (oddp x)
(cons x acc)
acc)))
((<= x end) (reverse acc))))
(defun odd-range (x)
(let* ((start (if (oddp x) x (1- x)))
(end (- start)))
(loop :for i :from start :downto end :by 2
:collect i)))